diff options
46 files changed, 582 insertions, 230 deletions
diff --git a/api/current.txt b/api/current.txt index ee9a9732a71c..37051403f187 100644 --- a/api/current.txt +++ b/api/current.txt @@ -7094,7 +7094,7 @@ package android.content.res { method public int getIndexCount(); method public int getInt(int, int); method public int getInteger(int, int); - method public deprecated int getLayoutDimension(int, java.lang.String); + method public int getLayoutDimension(int, java.lang.String); method public int getLayoutDimension(int, int); method public java.lang.String getNonResourceString(int); method public java.lang.String getPositionDescription(); @@ -8263,6 +8263,7 @@ package android.graphics { method public int getScaledWidth(int); method public final int getWidth(); method public final boolean hasAlpha(); + method public final boolean hasMipMap(); method public final boolean isMutable(); method public final boolean isPremultiplied(); method public final boolean isRecycled(); @@ -8271,6 +8272,7 @@ package android.graphics { method public boolean sameAs(android.graphics.Bitmap); method public void setDensity(int); method public void setHasAlpha(boolean); + method public final void setHasMipMap(boolean); method public void setPixel(int, int, int); method public void setPixels(int[], int, int, int, int, int, int); method public void writeToParcel(android.os.Parcel, int); @@ -16149,7 +16151,7 @@ package android.os { public class Looper { method public void dump(android.util.Printer, java.lang.String); - method public static android.os.Looper getMainLooper(); + method public static synchronized android.os.Looper getMainLooper(); method public java.lang.Thread getThread(); method public static void loop(); method public static android.os.Looper myLooper(); diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index aba87106d98c..8cbf5b1a5c8a 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; +import java.util.UUID; import android.net.LocalSocket; import java.nio.ByteOrder; import java.nio.ByteBuffer; @@ -140,7 +141,9 @@ public final class BluetoothSocket implements Closeable { throw new IOException("Invalid RFCOMM channel: " + port); } } - mUuid = uuid; + if(uuid != null) + mUuid = uuid; + else mUuid = new ParcelUuid(new UUID(0, 0)); mType = type; mAuth = auth; mEncrypt = encrypt; diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 1e4ad76f0b37..58df16773f7e 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -21,7 +21,6 @@ import android.accounts.AccountAndUser; import android.accounts.AccountManager; import android.accounts.AccountManagerService; import android.app.ActivityManager; -import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; @@ -154,7 +153,9 @@ public class SyncManager { private AlarmManager mAlarmService = null; private SyncStorageEngine mSyncStorageEngine; - final public SyncQueue mSyncQueue; + + // @GuardedBy("mSyncQueue") + private final SyncQueue mSyncQueue; protected final ArrayList<ActiveSyncContext> mActiveSyncContexts = Lists.newArrayList(); @@ -902,7 +903,9 @@ public class SyncManager { updateRunningAccounts(); - mSyncQueue.addPendingOperations(userId); + synchronized (mSyncQueue) { + mSyncQueue.addPendingOperations(userId); + } // Schedule sync for any accounts under started user final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId); @@ -1957,10 +1960,10 @@ public class SyncManager { synchronized (mSyncQueue) { if (isLoggable) { Log.v(TAG, "build the operation array, syncQueue size is " - + mSyncQueue.mOperationsMap.size()); + + mSyncQueue.getOperations().size()); } - Iterator<SyncOperation> operationIterator = - mSyncQueue.mOperationsMap.values().iterator(); + final Iterator<SyncOperation> operationIterator = mSyncQueue.getOperations() + .iterator(); final ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); @@ -2153,7 +2156,7 @@ public class SyncManager { runSyncFinishedOrCanceledLocked(null, toReschedule); scheduleSyncOperation(toReschedule.mSyncOperation); } - synchronized (mSyncQueue){ + synchronized (mSyncQueue) { mSyncQueue.remove(candidate); } dispatchSyncOperation(candidate); diff --git a/core/java/android/content/SyncQueue.java b/core/java/android/content/SyncQueue.java index 395658c196d4..14bfc5b52271 100644 --- a/core/java/android/content/SyncQueue.java +++ b/core/java/android/content/SyncQueue.java @@ -27,11 +27,14 @@ import android.util.Pair; import com.google.android.collect.Maps; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** + * Queue of pending sync operations. Not inherently thread safe, external + * callers are responsible for locking. * * @hide */ @@ -43,7 +46,7 @@ public class SyncQueue { // A Map of SyncOperations operationKey -> SyncOperation that is designed for // quick lookup of an enqueued SyncOperation. - public final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap(); + private final HashMap<String, SyncOperation> mOperationsMap = Maps.newHashMap(); public SyncQueue(SyncStorageEngine syncStorageEngine, final SyncAdaptersCache syncAdapters) { mSyncStorageEngine = syncStorageEngine; @@ -198,6 +201,10 @@ public class SyncQueue { } } + public Collection<SyncOperation> getOperations() { + return mOperationsMap.values(); + } + public void dump(StringBuilder sb) { final long now = SystemClock.elapsedRealtime(); sb.append("SyncQueue: ").append(mOperationsMap.size()).append(" operation(s)\n"); diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java index de97481775dd..10e7bff785d4 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/core/java/android/content/SyncStorageEngine.java @@ -609,23 +609,25 @@ public class SyncStorageEngine extends Handler { public void clearAllBackoffs(SyncQueue syncQueue) { boolean changed = false; synchronized (mAuthorities) { - for (AccountInfo accountInfo : mAccounts.values()) { - for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { - if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE - || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "clearAllBackoffs:" - + " authority:" + authorityInfo.authority - + " account:" + accountInfo.accountAndUser.account.name - + " user:" + accountInfo.accountAndUser.userId - + " backoffTime was: " + authorityInfo.backoffTime - + " backoffDelay was: " + authorityInfo.backoffDelay); + synchronized (syncQueue) { + for (AccountInfo accountInfo : mAccounts.values()) { + for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) { + if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE + || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "clearAllBackoffs:" + + " authority:" + authorityInfo.authority + + " account:" + accountInfo.accountAndUser.account.name + + " user:" + accountInfo.accountAndUser.userId + + " backoffTime was: " + authorityInfo.backoffTime + + " backoffDelay was: " + authorityInfo.backoffDelay); + } + authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; + authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; + syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, + accountInfo.accountAndUser.userId, authorityInfo.authority, 0); + changed = true; } - authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE; - authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE; - syncQueue.onBackoffChanged(accountInfo.accountAndUser.account, - accountInfo.accountAndUser.userId, authorityInfo.authority, 0); - changed = true; } } } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index a0283d302fd3..32cc7fd5aa1f 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -554,6 +554,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { manageSpaceActivityName = orig.manageSpaceActivityName; descriptionRes = orig.descriptionRes; uiOptions = orig.uiOptions; + backupAgentName = orig.backupAgentName; } diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index 0b917860c001..6def4a169703 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -264,7 +264,8 @@ public abstract class RegisteredServicesCache<V> { if (user.services == null) { generateServicesMap(userId); } - return Collections.unmodifiableCollection(user.services.values()); + return Collections.unmodifiableCollection( + new ArrayList<ServiceInfo<V>>(user.services.values())); } } diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 7f3b6b93619c..2968fbb50909 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -469,20 +469,13 @@ public class TypedArray { * {@link android.view.ViewGroup}'s layout_width and layout_height * attributes. This is only here for performance reasons; applications * should use {@link #getDimensionPixelSize}. - * + * * @param index Index of the attribute to retrieve. * @param name Textual name of attribute for error reporting. * * @return Attribute dimension value multiplied by the appropriate * metric and truncated to integer pixels. - * - * @throws RuntimeException - * if this TypedArray does not contain an entry for <code>index</code> - * - * @deprecated Use {@link #getLayoutDimension(int, int)} instead. - * */ - @Deprecated public int getLayoutDimension(int index, String name) { index *= AssetManager.STYLE_NUM_ENTRIES; final int[] data = mData; diff --git a/core/java/android/view/IDisplayContentChangeListener.aidl b/core/java/android/view/IDisplayContentChangeListener.aidl index 8f23ff66cdbc..ef7edeab3894 100644 --- a/core/java/android/view/IDisplayContentChangeListener.aidl +++ b/core/java/android/view/IDisplayContentChangeListener.aidl @@ -28,5 +28,6 @@ import android.graphics.Rect; oneway interface IDisplayContentChangeListener { void onWindowTransition(int displayId, int transition, in WindowInfo info); void onRectangleOnScreenRequested(int displayId, in Rect rectangle, boolean immediate); + void onWindowLayersChanged(int displayId); void onRotationChanged(int rotation); } diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index f692e05033b4..26a5b26889fd 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -20,7 +20,6 @@ import android.graphics.Canvas; import android.os.Handler; import android.os.Message; import android.widget.FrameLayout; -import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -44,20 +43,20 @@ import java.util.HashMap; * * <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService * (Context.LAYOUT_INFLATER_SERVICE);</pre> - * + * * <p> * To create a new LayoutInflater with an additional {@link Factory} for your * own views, you can use {@link #cloneInContext} to clone an existing * ViewFactory, and then call {@link #setFactory} on it to include your * Factory. - * + * * <p> * For performance reasons, view inflation relies heavily on pre-processing of * XML files that is done at build time. Therefore, it is not currently possible * to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; * it only works with an XmlPullParser returned from a compiled resource * (R.<em>something</em> file.) - * + * * @see Context#getSystemService */ public abstract class LayoutInflater { @@ -83,7 +82,7 @@ public abstract class LayoutInflater { private static final HashMap<String, Constructor<? extends View>> sConstructorMap = new HashMap<String, Constructor<? extends View>>(); - + private HashMap<String, Boolean> mFilterMap; private static final String TAG_MERGE = "merge"; @@ -94,36 +93,36 @@ public abstract class LayoutInflater { /** * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed * to be inflated. - * + * */ public interface Filter { /** * Hook to allow clients of the LayoutInflater to restrict the set of Views * that are allowed to be inflated. - * + * * @param clazz The class object for the View that is about to be inflated - * + * * @return True if this class is allowed to be inflated, or false otherwise */ @SuppressWarnings("unchecked") boolean onLoadClass(Class clazz); } - + public interface Factory { /** * Hook you can supply that is called when inflating from a LayoutInflater. * You can use this to customize the tag names available in your XML * layout files. - * + * * <p> * Note that it is good practice to prefix these custom names with your * package (i.e., com.coolcompany.apps) to avoid conflicts with system * names. - * + * * @param name Tag name to be inflated. * @param context The context the view is being created in. * @param attrs Inflation attributes as specified in XML file. - * + * * @return View Newly created view. Return null for the default * behavior. */ @@ -151,14 +150,14 @@ public abstract class LayoutInflater { private static class FactoryMerger implements Factory2 { private final Factory mF1, mF2; private final Factory2 mF12, mF22; - + FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) { mF1 = f1; mF2 = f2; mF12 = f12; mF22 = f22; } - + public View onCreateView(String name, Context context, AttributeSet attrs) { View v = mF1.onCreateView(name, context, attrs); if (v != null) return v; @@ -173,13 +172,13 @@ public abstract class LayoutInflater { : mF2.onCreateView(name, context, attrs); } } - + /** * Create a new LayoutInflater instance associated with a particular Context. * Applications will almost always want to use * {@link Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}. - * + * * @param context The Context in which this LayoutInflater will create its * Views; most importantly, this supplies the theme from which the default * values for their attributes are retrieved. @@ -192,7 +191,7 @@ public abstract class LayoutInflater { * Create a new LayoutInflater instance that is a copy of an existing * LayoutInflater, optionally with its Context changed. For use in * implementing {@link #cloneInContext}. - * + * * @param original The original LayoutInflater to copy. * @param newContext The new Context to use. */ @@ -203,7 +202,7 @@ public abstract class LayoutInflater { mPrivateFactory = original.mPrivateFactory; mFilter = original.mFilter; } - + /** * Obtains the LayoutInflater from the given context. */ @@ -221,15 +220,15 @@ public abstract class LayoutInflater { * pointing to a different Context than the original. This is used by * {@link ContextThemeWrapper} to create a new LayoutInflater to go along * with the new Context theme. - * + * * @param newContext The new Context to associate with the new LayoutInflater. * May be the same as the original Context if desired. - * + * * @return Returns a brand spanking new LayoutInflater object associated with * the given Context. */ public abstract LayoutInflater cloneInContext(Context newContext); - + /** * Return the context we are running in, for access to resources, class * loader, etc. @@ -265,7 +264,7 @@ public abstract class LayoutInflater { * called on each element name as the xml is parsed. If the factory returns * a View, that is added to the hierarchy. If it returns null, the next * factory default {@link #onCreateView} method is called. - * + * * <p>If you have an existing * LayoutInflater and want to add your own factory to it, use * {@link #cloneInContext} to clone the existing instance and then you @@ -321,13 +320,13 @@ public abstract class LayoutInflater { public Filter getFilter() { return mFilter; } - + /** * Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated * which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will * throw an {@link InflateException}. This filter will replace any previous filter set on this * LayoutInflater. - * + * * @param filter The Filter which restricts the set of Views that are allowed to be inflated. * This filter will replace any previous filter set on this LayoutInflater. */ @@ -341,7 +340,7 @@ public abstract class LayoutInflater { /** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. - * + * * @param resource ID for an XML layout resource to load (e.g., * <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy. @@ -361,7 +360,7 @@ public abstract class LayoutInflater { * reasons, view inflation relies heavily on pre-processing of XML files * that is done at build time. Therefore, it is not currently possible to * use LayoutInflater with an XmlPullParser over a plain XML file at runtime. - * + * * @param parser XML dom node containing the description of the view * hierarchy. * @param root Optional view to be the parent of the generated hierarchy. @@ -376,7 +375,7 @@ public abstract class LayoutInflater { /** * Inflate a new view hierarchy from the specified xml resource. Throws * {@link InflateException} if there is an error. - * + * * @param resource ID for an XML layout resource to load (e.g., * <code>R.layout.main_page</code>) * @param root Optional view to be the parent of the generated hierarchy (if @@ -408,7 +407,7 @@ public abstract class LayoutInflater { * reasons, view inflation relies heavily on pre-processing of XML files * that is done at build time. Therefore, it is not currently possible to * use LayoutInflater with an XmlPullParser over a plain XML file at runtime. - * + * * @param parser XML dom node containing the description of the view * hierarchy. * @param root Optional view to be the parent of the generated hierarchy (if @@ -443,7 +442,7 @@ public abstract class LayoutInflater { } final String name = parser.getName(); - + if (DEBUG) { System.out.println("**************************"); System.out.println("Creating root view: " @@ -529,17 +528,17 @@ public abstract class LayoutInflater { * Low-level function for instantiating a view by name. This attempts to * instantiate a view class of the given <var>name</var> found in this * LayoutInflater's ClassLoader. - * + * * <p> * There are two things that can happen in an error case: either the * exception describing the error will be thrown, or a null will be * returned. You must deal with both possibilities -- the former will happen * the first time createView() is called for a class of a particular name, * the latter every time there-after for that class name. - * + * * @param name The full name of the class to be instantiated. * @param attrs The XML attributes supplied for this instance. - * + * * @return View The newly instantiated view, or null. */ public final View createView(String name, String prefix, AttributeSet attrs) @@ -552,7 +551,7 @@ public abstract class LayoutInflater { // Class not found in the cache, see if it's real, and try to add it clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); - + if (mFilter != null && clazz != null) { boolean allowed = mFilter.onLoadClass(clazz); if (!allowed) { @@ -570,7 +569,7 @@ public abstract class LayoutInflater { // New class -- remember whether it is allowed clazz = mContext.getClassLoader().loadClass( prefix != null ? (prefix + name) : name).asSubclass(View.class); - + boolean allowed = clazz != null && mFilter.onLoadClass(clazz); mFilterMap.put(name, allowed); if (!allowed) { @@ -633,10 +632,10 @@ public abstract class LayoutInflater { * given the xml element name. Override it to handle custom view objects. If * you override this in your subclass be sure to call through to * super.onCreateView(name) for names you do not recognize. - * + * * @param name The fully qualified class name of the View to be create. * @param attrs An AttributeSet of attributes to apply to the View. - * + * * @return View The View created. */ protected View onCreateView(String name, AttributeSet attrs) @@ -680,7 +679,7 @@ public abstract class LayoutInflater { if (view == null && mPrivateFactory != null) { view = mPrivateFactory.onCreateView(parent, name, mContext, attrs); } - + if (view == null) { if (-1 == name.indexOf('.')) { view = onCreateView(parent, name, attrs); @@ -727,7 +726,7 @@ public abstract class LayoutInflater { } final String name = parser.getName(); - + if (TAG_REQUEST_FOCUS.equals(name)) { parseRequestFocus(parser, parent); } else if (TAG_INCLUDE.equals(name)) { @@ -742,7 +741,7 @@ public abstract class LayoutInflater { final ViewGroup viewGroup = (ViewGroup) parent; final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); rInflate(parser, view, attrs, true); - viewGroup.addView(view, params); + viewGroup.addView(view, params); } else { final View view = createViewFromTag(parent, name, attrs); final ViewGroup viewGroup = (ViewGroup) parent; @@ -811,14 +810,21 @@ public abstract class LayoutInflater { // We try to load the layout params set in the <include /> tag. If // they don't exist, we will rely on the layout params set in the // included XML file. - TypedArray ta = getContext().obtainStyledAttributes(attrs, - R.styleable.ViewGroup_Layout); - boolean definesBothWidthAndHeight = - ta.hasValue(R.styleable.ViewGroup_Layout_layout_width) && - ta.hasValue(R.styleable.ViewGroup_Layout_layout_height); - AttributeSet attributes = definesBothWidthAndHeight ? attrs : childAttrs; - view.setLayoutParams(group.generateLayoutParams(attributes)); - ta.recycle(); + // During a layoutparams generation, a runtime exception is thrown + // if either layout_width or layout_height is missing. We catch + // this exception and set localParams accordingly: true means we + // successfully loaded layout params from the <include /> tag, + // false means we need to rely on the included layout params. + ViewGroup.LayoutParams params = null; + try { + params = group.generateLayoutParams(attrs); + } catch (RuntimeException e) { + params = group.generateLayoutParams(childAttrs); + } finally { + if (params != null) { + view.setLayoutParams(params); + } + } // Inflate all children. rInflate(childParser, view, childAttrs, true); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 9ce7df943d9e..6c1049b940af 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5611,19 +5611,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** - * Extracts the <code>width</code> and <code>height</code> layout parameters - * from the supplied TypedArray, <code>a</code>, and assigns them - * to the appropriate fields. If, <code>a</code>, does not contain an - * entry for either attribute, the value, {@link ViewGroup.LayoutParams#WRAP_CONTENT}, - * is used as a default. + * Extracts the layout parameters from the supplied attributes. * * @param a the style attributes to extract the parameters from * @param widthAttr the identifier of the width attribute * @param heightAttr the identifier of the height attribute */ protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { - width = a.getLayoutDimension(widthAttr, WRAP_CONTENT); - height = a.getLayoutDimension(heightAttr, WRAP_CONTENT); + width = a.getLayoutDimension(widthAttr, "layout_width"); + height = a.getLayoutDimension(heightAttr, "layout_height"); } /** diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 646fe7e23239..3b5e75b91d97 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -241,6 +241,7 @@ public abstract class AbsSeekBar extends ProgressBar { @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); updateThumbPos(w, h); } @@ -555,4 +556,23 @@ public abstract class AbsSeekBar extends ProgressBar { } return false; } + + @Override + public void onRtlPropertiesChanged(int layoutDirection) { + super.onRtlPropertiesChanged(layoutDirection); + + int max = getMax(); + float scale = max > 0 ? (float) getProgress() / (float) max : 0; + + Drawable thumb = mThumb; + if (thumb != null) { + setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE); + /* + * Since we draw translated, the drawable's bounds that it signals + * for invalidation won't be the actual bounds we want invalidated, + * so just invalidate this whole view. + */ + invalidate(); + } + } } diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 45f30df7b40d..e15877640758 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -608,12 +608,6 @@ public class FrameLayout extends ViewGroup { */ public int gravity = -1; - @Override - protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { - width = a.getLayoutDimension(widthAttr, MATCH_PARENT); - height = a.getLayoutDimension(heightAttr, MATCH_PARENT); - } - /** * {@inheritDoc} */ diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java index 42d63b24f9b8..78d05b0987bf 100644 --- a/core/java/android/widget/RadioGroup.java +++ b/core/java/android/widget/RadioGroup.java @@ -297,6 +297,33 @@ public class RadioGroup extends LinearLayout { public LayoutParams(MarginLayoutParams source) { super(source); } + + /** + * <p>Fixes the child's width to + * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} and the child's + * height to {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} + * when not specified in the XML file.</p> + * + * @param a the styled attributes set + * @param widthAttr the width attribute to fetch + * @param heightAttr the height attribute to fetch + */ + @Override + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { + + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = WRAP_CONTENT; + } + + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } + } } /** diff --git a/core/java/android/widget/TableLayout.java b/core/java/android/widget/TableLayout.java index 113299a73cee..399b4fa14544 100644 --- a/core/java/android/widget/TableLayout.java +++ b/core/java/android/widget/TableLayout.java @@ -741,9 +741,14 @@ public class TableLayout extends LinearLayout { * @param heightAttr the height attribute to fetch */ @Override - protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { + protected void setBaseAttributes(TypedArray a, + int widthAttr, int heightAttr) { this.width = MATCH_PARENT; - this.height = a.getLayoutDimension(heightAttr, WRAP_CONTENT); + if (a.hasValue(heightAttr)) { + this.height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + this.height = WRAP_CONTENT; + } } } diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java index 3f8f9dae640e..68ffd733f6ad 100644 --- a/core/java/android/widget/TableRow.java +++ b/core/java/android/widget/TableRow.java @@ -505,8 +505,19 @@ public class TableRow extends LinearLayout { @Override protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { - width = a.getLayoutDimension(widthAttr, MATCH_PARENT); - height = a.getLayoutDimension(heightAttr, WRAP_CONTENT); + // We don't want to force users to specify a layout_width + if (a.hasValue(widthAttr)) { + width = a.getLayoutDimension(widthAttr, "layout_width"); + } else { + width = MATCH_PARENT; + } + + // We don't want to force users to specify a layout_height + if (a.hasValue(heightAttr)) { + height = a.getLayoutDimension(heightAttr, "layout_height"); + } else { + height = WRAP_CONTENT; + } } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 751ed7c4549a..8e5ff40fac65 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -6321,7 +6321,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mDeferScroll >= 0) { int curs = mDeferScroll; mDeferScroll = -1; - bringPointIntoView(curs); + bringPointIntoView(Math.min(curs, mText.length())); } if (changed && mEditor != null) mEditor.invalidateTextDisplayList(); } diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index fd7a6a757a35..f485e0357638 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -7,7 +7,7 @@ #include "SkUnPreMultiply.h"
#include <binder/Parcel.h>
-#include "android_os_Parcel.h" +#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "android_nio_utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
@@ -353,6 +353,15 @@ static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap, bitmap->setIsOpaque(!hasAlpha);
}
+static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
+ return bitmap->hasHardwareMipMap();
+}
+
+static void Bitmap_setHasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap,
+ jboolean hasMipMap) {
+ bitmap->setHasHardwareMipMap(hasMipMap);
+}
+
///////////////////////////////////////////////////////////////////////////////
static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
@@ -666,6 +675,8 @@ static JNINativeMethod gBitmapMethods[] = { { "nativeConfig", "(I)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
{ "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
+ { "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap },
+ { "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap },
{ "nativeCreateFromParcel",
"(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
(void*)Bitmap_createFromParcel },
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml index 20726d0050bb..981fe6d0da55 100644 --- a/core/res/res/layout-port/keyguard_host_view.xml +++ b/core/res/res/layout-port/keyguard_host_view.xml @@ -33,7 +33,8 @@ <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper android:id="@+id/view_flipper" - android:layout_height="0dp" + android:layout_width="match_parent" + android:layout_height="0dip" android:clipChildren="false" android:clipToPadding="false" android:layout_weight="1" diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/core/res/res/layout-port/keyguard_status_area.xml index e0a49dca37b7..c1f6aab1f0ac 100644 --- a/core/res/res/layout-port/keyguard_status_area.xml +++ b/core/res/res/layout-port/keyguard_status_area.xml @@ -45,6 +45,8 @@ <TextView android:id="@+id/alarm_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_marginEnd="@dimen/kg_status_line_font_right_margin" android:singleLine="true" android:ellipsize="marquee" @@ -93,4 +95,4 @@ android:textSize="@dimen/kg_status_line_font_size" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml index f21254a831e6..405ac141f2db 100644 --- a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml +++ b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml @@ -78,4 +78,4 @@ android:textAppearance="?android:attr/textAppearance" android:textSize="@dimen/kg_status_line_font_size" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/core/res/res/layout/default_navigation.xml b/core/res/res/layout/default_navigation.xml index b13103cf1e7d..b216ded192e4 100644 --- a/core/res/res/layout/default_navigation.xml +++ b/core/res/res/layout/default_navigation.xml @@ -18,6 +18,8 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keyguard_click_area" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:gravity="center"> <!-- message area for security screen --> diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml index ab8aa85ba55c..81916f73cb09 100644 --- a/core/res/res/layout/keyguard_password_view.xml +++ b/core/res/res/layout/keyguard_password_view.xml @@ -53,6 +53,7 @@ since the backspace/IME switcher looks better inside --> <LinearLayout android:layout_gravity="center_vertical|fill_horizontal" + android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal" android:background="#70000000" diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml index 163dc15223eb..ae59d1de99ec 100644 --- a/core/res/res/layout/keyguard_sim_pin_view.xml +++ b/core/res/res/layout/keyguard_sim_pin_view.xml @@ -91,6 +91,7 @@ <!-- Numeric keyboard --> <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" android:layout_width="match_parent" + android:layout_height="wrap_content" android:layout_marginStart="4dip" android:layout_marginEnd="4dip" android:paddingTop="4dip" diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml index 6e45b0b26541..414806fb4097 100644 --- a/core/res/res/layout/keyguard_sim_puk_view.xml +++ b/core/res/res/layout/keyguard_sim_puk_view.xml @@ -93,6 +93,7 @@ <!-- Numeric keyboard --> <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" android:layout_width="match_parent" + android:layout_height="wrap_content" android:layout_marginStart="4dip" android:layout_marginEnd="4dip" android:paddingTop="4dip" diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 6238edb6d011..22ecc6135172 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -1030,6 +1030,51 @@ public final class Bitmap implements Parcelable { } /** + * Indicates whether the renderer responsible for drawing this + * bitmap should attempt to use mipmaps when this bitmap is drawn + * scaled down. + * + * If you know that you are going to draw this bitmap at less than + * 50% of its original size, you may be able to obtain a higher + * quality + * + * This property is only a suggestion that can be ignored by the + * renderer. It is not guaranteed to have any effect. + * + * @return true if the renderer should attempt to use mipmaps, + * false otherwise + * + * @see #setHasMipMap(boolean) + */ + public final boolean hasMipMap() { + return nativeHasMipMap(mNativeBitmap); + } + + /** + * Set a hint for the renderer responsible for drawing this bitmap + * indicating that it should attempt to use mipmaps when this bitmap + * is drawn scaled down. + * + * If you know that you are going to draw this bitmap at less than + * 50% of its original size, you may be able to obtain a higher + * quality by turning this property on. + * + * Note that if the renderer respects this hint it might have to + * allocate extra memory to hold the mipmap levels for this bitmap. + * + * This property is only a suggestion that can be ignored by the + * renderer. It is not guaranteed to have any effect. + * + * @param hasMipMap indicates whether the renderer should attempt + * to use mipmaps + * + * @see #hasMipMap() + */ + public final void setHasMipMap(boolean hasMipMap) { + nativeSetHasMipMap(mNativeBitmap, hasMipMap); + } + + /** * Fills the bitmap's pixels with the specified {@link Color}. * * @throws IllegalStateException if the bitmap is not mutable. @@ -1356,7 +1401,6 @@ public final class Bitmap implements Parcelable { private static native int nativeHeight(int nativeBitmap); private static native int nativeRowBytes(int nativeBitmap); private static native int nativeConfig(int nativeBitmap); - private static native boolean nativeHasAlpha(int nativeBitmap); private static native int nativeGetPixel(int nativeBitmap, int x, int y); private static native void nativeGetPixels(int nativeBitmap, int[] pixels, @@ -1385,7 +1429,10 @@ public final class Bitmap implements Parcelable { int[] offsetXY); private static native void nativePrepareToDraw(int nativeBitmap); + private static native boolean nativeHasAlpha(int nativeBitmap); private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha); + private static native boolean nativeHasMipMap(int nativeBitmap); + private static native void nativeSetHasMipMap(int nBitmap, boolean hasMipMap); private static native boolean nativeSameAs(int nb0, int nb1); /* package */ final int ni() { diff --git a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java index 188e04c1a90c..41bdd2531c8c 100644 --- a/graphics/java/android/renderscript/ScriptIntrinsicLUT.java +++ b/graphics/java/android/renderscript/ScriptIntrinsicLUT.java @@ -41,7 +41,7 @@ public final class ScriptIntrinsicLUT extends ScriptIntrinsic { mCache[ct + 512] = (byte)ct; mCache[ct + 768] = (byte)ct; } - bindAllocation(mTables, 0); + setVar(0, mTables); } /** diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2b500912e718..406d5e955788 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -49,7 +49,7 @@ namespace uirenderer { #define ALPHA_THRESHOLD 0 -#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST) +#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST) /////////////////////////////////////////////////////////////////////////////// // Globals @@ -1730,35 +1730,22 @@ status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, float* vertices, int* colors, SkPaint* paint) { - // TODO: Do a quickReject if (!vertices || mSnapshot->isIgnored()) { return DrawGlInfo::kStatusDone; } - mCaches.activeTexture(0); - Texture* texture = mCaches.textureCache.get(bitmap); - if (!texture) return DrawGlInfo::kStatusDone; - const AutoTexture autoCleanup(texture); - - texture->setWrap(GL_CLAMP_TO_EDGE, true); - texture->setFilter(FILTER(paint), true); - - int alpha; - SkXfermode::Mode mode; - getAlphaAndMode(paint, &alpha, &mode); - - const uint32_t count = meshWidth * meshHeight * 6; - + // TODO: We should compute the bounding box when recording the display list float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; float bottom = FLT_MIN; - const bool hasActiveLayer = hasLayer(); + const uint32_t count = meshWidth * meshHeight * 6; // TODO: Support the colors array TextureVertex mesh[count]; TextureVertex* vertex = mesh; + for (int32_t y = 0; y < meshHeight; y++) { for (int32_t x = 0; x < meshWidth; x++) { uint32_t i = (y * (meshWidth + 1) + x) * 2; @@ -1785,17 +1772,31 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1); TextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2); - if (hasActiveLayer) { - // TODO: This could be optimized to avoid unnecessary ops - left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx]))); - top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy]))); - right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx]))); - bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy]))); - } + // TODO: This could be optimized to avoid unnecessary ops + left = fminf(left, fminf(vertices[ax], fminf(vertices[bx], vertices[cx]))); + top = fminf(top, fminf(vertices[ay], fminf(vertices[by], vertices[cy]))); + right = fmaxf(right, fmaxf(vertices[ax], fmaxf(vertices[bx], vertices[cx]))); + bottom = fmaxf(bottom, fmaxf(vertices[ay], fmaxf(vertices[by], vertices[cy]))); } } - if (hasActiveLayer) { + if (quickReject(left, top, right, bottom)) { + return DrawGlInfo::kStatusDone; + } + + mCaches.activeTexture(0); + Texture* texture = mCaches.textureCache.get(bitmap); + if (!texture) return DrawGlInfo::kStatusDone; + const AutoTexture autoCleanup(texture); + + texture->setWrap(GL_CLAMP_TO_EDGE, true); + texture->setFilter(FILTER(paint), true); + + int alpha; + SkXfermode::Mode mode; + getAlphaAndMode(paint, &alpha, &mode); + + if (hasLayer()) { dirtyLayer(left, top, right, bottom, *mSnapshot->transform); } diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 03e2172a7aaf..8d88bdce3c9e 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -36,6 +36,8 @@ struct Texture { minFilter = GL_NEAREST; magFilter = GL_NEAREST; + mipMap = false; + firstFilter = true; firstWrap = true; @@ -83,6 +85,8 @@ struct Texture { glBindTexture(renderTarget, id); } + if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR; + glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min); glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag); } @@ -116,7 +120,12 @@ struct Texture { * Optional, size of the original bitmap. */ uint32_t bitmapSize; + /** + * Indicates whether this texture will use trilinear filtering. + */ + bool mipMap; +private: /** * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE. */ @@ -129,7 +138,6 @@ struct Texture { GLenum minFilter; GLenum magFilter; -private: bool firstFilter; bool firstWrap; }; // struct Texture diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 9fb61e486266..431367a34354 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -22,6 +22,7 @@ #include <utils/threads.h> +#include "Caches.h" #include "TextureCache.h" #include "Properties.h" @@ -73,6 +74,8 @@ void TextureCache::init() { INIT_LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize); mDebugEnabled = readDebugLevel() & kDebugCaches; + + mHasNPot = Caches::getInstance().extensions.hasNPot(); } /////////////////////////////////////////////////////////////////////////////// @@ -216,8 +219,11 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege return; } + // If the texture had mipmap enabled but not anymore, + // force a glTexImage2D to discard the mipmap levels const bool resize = !regenerate || bitmap->width() != int(texture->width) || - bitmap->height() != int(texture->height); + bitmap->height() != int(texture->height) || + (regenerate && mHasNPot && texture->mipMap && !bitmap->hasHardwareMipMap()); if (!regenerate) { glGenTextures(1, &texture->id); @@ -228,25 +234,22 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege texture->height = bitmap->height(); glBindTexture(GL_TEXTURE_2D, texture->id); - if (!regenerate) { - glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); - } switch (bitmap->getConfig()) { case SkBitmap::kA8_Config: - if (!regenerate) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels()); texture->blend = true; break; case SkBitmap::kRGB_565_Config: + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->height, GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels()); texture->blend = false; break; case SkBitmap::kARGB_8888_Config: + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height, GL_UNSIGNED_BYTE, bitmap->getPixels()); // Do this after calling getPixels() to make sure Skia's deferred @@ -255,6 +258,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege break; case SkBitmap::kARGB_4444_Config: case SkBitmap::kIndex8_Config: + glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); uploadLoFiTexture(resize, bitmap, texture->width, texture->height); texture->blend = !bitmap->isOpaque(); break; @@ -263,6 +267,13 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege break; } + if (mHasNPot) { + texture->mipMap = bitmap->hasHardwareMipMap(); + if (texture->mipMap) { + glGenerateMipmap(GL_TEXTURE_2D); + } + } + if (!regenerate) { texture->setFilter(GL_NEAREST); texture->setWrap(GL_CLAMP_TO_EDGE); diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 31a2e3d7e81f..8e190921e7f8 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -138,6 +138,7 @@ private: float mFlushRate; + bool mHasNPot; bool mDebugEnabled; Vector<SkBitmap*> mGarbage; diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 6877cba59fff..0958f70ffbd4 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -31,8 +31,10 @@ import android.os.SystemProperties; import android.renderscript.Matrix4f; import android.service.wallpaper.WallpaperService; import android.util.Log; +import android.view.Display; import android.view.MotionEvent; import android.view.SurfaceHolder; +import android.view.WindowManager; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; @@ -108,6 +110,7 @@ public class ImageWallpaper extends WallpaperService { Bitmap mBackground; int mBackgroundWidth = -1, mBackgroundHeight = -1; + int mLastRotation = -1; float mXOffset; float mYOffset; @@ -156,7 +159,7 @@ public class ImageWallpaper extends WallpaperService { mBackgroundWidth = mBackgroundHeight = -1; mBackground = null; mRedrawNeeded = true; - drawFrameLocked(false); + drawFrameLocked(); } } } @@ -225,7 +228,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onVisibilityChanged(boolean visible) { if (DEBUG) { - Log.d(TAG, "onVisibilityChanged: visible=" + visible); + Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible); } synchronized (mLock) { @@ -234,7 +237,7 @@ public class ImageWallpaper extends WallpaperService { Log.d(TAG, "Visibility changed to visible=" + visible); } mVisible = visible; - drawFrameLocked(false); + drawFrameLocked(); } } } @@ -263,7 +266,7 @@ public class ImageWallpaper extends WallpaperService { mYOffset = yOffset; mOffsetsChanged = true; } - drawFrameLocked(false); + drawFrameLocked(); } } @@ -276,80 +279,81 @@ public class ImageWallpaper extends WallpaperService { super.onSurfaceChanged(holder, format, width, height); synchronized (mLock) { - mRedrawNeeded = true; - mBackgroundWidth = mBackgroundHeight = -1; - drawFrameLocked(true); + drawFrameLocked(); } } @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + mBackgroundWidth = mBackgroundHeight = -1; + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + mBackgroundWidth = mBackgroundHeight = -1; + } + + @Override public void onSurfaceRedrawNeeded(SurfaceHolder holder) { if (DEBUG) { - Log.d(TAG, "onSurfaceRedrawNeeded:"); + Log.d(TAG, "onSurfaceRedrawNeeded"); } super.onSurfaceRedrawNeeded(holder); synchronized (mLock) { - mRedrawNeeded = true; - drawFrameLocked(false); + drawFrameLocked(); } } - void drawFrameLocked(boolean force) { - if (!force) { - if (!mVisible) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible."); - } - return; - } - if (!mRedrawNeeded && !mOffsetsChanged) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since redraw is not needed " - + "and offsets have not changed."); - } - return; + void drawFrameLocked() { + SurfaceHolder sh = getSurfaceHolder(); + final Rect frame = sh.getSurfaceFrame(); + final int dw = frame.width(); + final int dh = frame.height(); + int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)). + getDefaultDisplay().getRotation(); + + boolean redrawNeeded = dw != mBackgroundWidth || dh != mBackgroundHeight || + newRotation != mLastRotation; + if (!redrawNeeded && !mOffsetsChanged) { + if (DEBUG) { + Log.d(TAG, "Suppressed drawFrame since redraw is not needed " + + "and offsets have not changed."); } + return; } - // If we don't yet know the size of the wallpaper bitmap, - // we need to get it now. - boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ; - - // If we somehow got to this point after we have last flushed - // the wallpaper, well we really need it to draw again. So - // seems like we need to reload it. Ouch. - updateWallpaper = updateWallpaper || mBackground == null; + mLastRotation = newRotation; - if (updateWallpaper) { + // Load bitmap if it is not yet loaded or if it was loaded at a different size + if (mBackground == null || dw != mBackgroundWidth || dw != mBackgroundHeight) { + if (DEBUG) { + Log.d(TAG, "Reloading bitmap"); + } + mWallpaperManager.forgetLoadedWallpaper(); updateWallpaperLocked(); } - SurfaceHolder sh = getSurfaceHolder(); - final Rect frame = sh.getSurfaceFrame(); - final int dw = frame.width(); - final int dh = frame.height(); final int availw = dw - mBackgroundWidth; final int availh = dh - mBackgroundHeight; int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2); int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2); mOffsetsChanged = false; - if (!force && !mRedrawNeeded - && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { + mRedrawNeeded = false; + mLastXTranslation = xPixels; + mLastYTranslation = yPixels; + if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { if (DEBUG) { Log.d(TAG, "Suppressed drawFrame since the image has not " + "actually moved an integral number of pixels."); } return; } - mRedrawNeeded = false; - mLastXTranslation = xPixels; - mLastYTranslation = yPixels; if (DEBUG) { - Log.d(TAG, "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x" - + mBackgroundHeight + " SurfaceFrame=" + frame.toShortString() - + " X,YOffset=" + mXOffset + "," + mYOffset); + Log.d(TAG, "Redrawing wallpaper"); } if (mIsHwAccelerated) { if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { @@ -429,7 +433,6 @@ public class ImageWallpaper extends WallpaperService { final float bottom = top + mBackgroundHeight; final Rect frame = sh.getSurfaceFrame(); - final Matrix4f ortho = new Matrix4f(); ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f); @@ -437,7 +440,7 @@ public class ImageWallpaper extends WallpaperService { final int texture = loadTexture(mBackground); final int program = buildProgram(sSimpleVS, sSimpleFS); - + final int attribPosition = glGetAttribLocation(program, "position"); final int attribTexCoords = glGetAttribLocation(program, "texCoords"); final int uniformTexture = glGetUniformLocation(program, "texture"); @@ -460,7 +463,7 @@ public class ImageWallpaper extends WallpaperService { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); } - + // drawQuad triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, @@ -471,12 +474,12 @@ public class ImageWallpaper extends WallpaperService { TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - + if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { throw new RuntimeException("Cannot swap buffers"); } checkEglError(); - + finishGL(); return true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 64bce22d2a8d..d4ccf9655366 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -541,8 +541,6 @@ public class PhoneStatusBar extends BaseStatusBar { } if (mSettingsPanel != null) { - mSettingsPanel.setBar(mStatusBarView); - if (!ActivityManager.isHighEndGfx()) { mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor( R.color.notification_panel_solid_background))); @@ -563,6 +561,7 @@ public class PhoneStatusBar extends BaseStatusBar { mSettingsPanel.setQuickSettings(mQS); } mQS.setService(this); + mQS.setBar(mStatusBarView); mQS.setup(mNetworkController, mBluetoothController, mBatteryController, mLocationController); } else { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java index 78fdda3897a0..04ab8713eaa6 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java @@ -75,7 +75,7 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu public void onDetachedFromWindow() { if (DEBUG) Log.d(TAG, "onDetachedFromWindow()"); if (mBiometricUnlock != null) { - mBiometricUnlock.stopAndShowBackup(); + mBiometricUnlock.stop(); } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index ebc54b32a701..b86e5b8564ca 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -611,6 +611,7 @@ public class KeyguardHostView extends KeyguardViewBase { int layoutId = getLayoutIdFor(securityMode); if (view == null && layoutId != 0) { final LayoutInflater inflater = LayoutInflater.from(mContext); + if (DEBUG) Log.v(TAG, "inflating id = " + layoutId); View v = inflater.inflate(layoutId, this, false); mSecurityViewContainer.addView(v); updateSecurityView(v); diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 69489274423e..63eeeb32cecd 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -1340,6 +1340,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run */ @Override public ProviderProperties getProviderProperties(String provider) { + if (mProvidersByName.get(provider) == null) { + return null; + } + checkPermissionForProvider(getBestCallingPermission(), provider); LocationProviderInterface p; diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java index c8931f4bf2b9..caf37b76ea23 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java @@ -38,6 +38,7 @@ import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.provider.Settings; import android.util.Property; import android.util.Slog; @@ -662,12 +663,33 @@ public final class ScreenMagnifier implements EventStreamTransformation { while (mDelayedEventQueue != null) { MotionEventInfo info = mDelayedEventQueue; mDelayedEventQueue = info.mNext; - ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mRawEvent, - info.mPolicyFlags); + final long offset = SystemClock.uptimeMillis() - info.mCachedTimeMillis; + MotionEvent event = obtainEventWithOffsetTimeAndDownTime(info.mEvent, offset); + MotionEvent rawEvent = obtainEventWithOffsetTimeAndDownTime(info.mRawEvent, offset); + ScreenMagnifier.this.onMotionEvent(event, rawEvent, info.mPolicyFlags); + event.recycle(); + rawEvent.recycle(); info.recycle(); } } + private MotionEvent obtainEventWithOffsetTimeAndDownTime(MotionEvent event, long offset) { + final int pointerCount = event.getPointerCount(); + PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount); + PointerProperties[] properties = getTempPointerPropertiesWithMinSize(pointerCount); + for (int i = 0; i < pointerCount; i++) { + event.getPointerCoords(i, coords[i]); + event.getPointerProperties(i, properties[i]); + } + final long downTime = event.getDownTime() + offset; + final long eventTime = event.getEventTime() + offset; + return MotionEvent.obtain(downTime, eventTime, + event.getAction(), pointerCount, properties, coords, + event.getMetaState(), event.getButtonState(), + 1.0f, 1.0f, event.getDeviceId(), event.getEdgeFlags(), + event.getSource(), event.getFlags()); + } + private void clearDelayedMotionEvents() { while (mDelayedEventQueue != null) { MotionEventInfo info = mDelayedEventQueue; @@ -746,6 +768,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { public MotionEvent mEvent; public MotionEvent mRawEvent; public int mPolicyFlags; + public long mCachedTimeMillis; public static MotionEventInfo obtain(MotionEvent event, MotionEvent rawEvent, int policyFlags) { @@ -770,6 +793,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { mEvent = MotionEvent.obtain(event); mRawEvent = MotionEvent.obtain(rawEvent); mPolicyFlags = policyFlags; + mCachedTimeMillis = SystemClock.uptimeMillis(); } public void recycle() { @@ -793,6 +817,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { mRawEvent.recycle(); mRawEvent = null; mPolicyFlags = 0; + mCachedTimeMillis = 0; } } @@ -850,6 +875,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { private static final int MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED = 3; private static final int MESSAGE_ON_WINDOW_TRANSITION = 4; private static final int MESSAGE_ON_ROTATION_CHANGED = 5; + private static final int MESSAGE_ON_WINDOW_LAYERS_CHANGED = 6; private final Handler mHandler = new MyHandler(); @@ -880,24 +906,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { mDisplayContentChangeListener = new IDisplayContentChangeListener.Stub() { @Override public void onWindowTransition(int displayId, int transition, WindowInfo info) { - Message message = mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION, - transition, 0, WindowInfo.obtain(info)); - // TODO: This makes me quite unhappy but for the time being the - // least risky fix for cases where the keyguard is removed but - // the windows it force hides are not made visible yet. Hence, - // we would compute the magnified frame before we have a stable - // state. One more reason to move the magnified frame computation - // in the window manager! - if (info.type == WindowManager.LayoutParams.TYPE_KEYGUARD - || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG - && (transition == WindowManagerPolicy.TRANSIT_EXIT - || transition == WindowManagerPolicy.TRANSIT_HIDE)) { - final long delay = (long) (2 * mLongAnimationDuration - * mWindowAnimationScale); - mHandler.sendMessageDelayed(message, delay); - } else { - message.sendToTarget(); - } + mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION, + transition, 0, WindowInfo.obtain(info)).sendToTarget(); } @Override @@ -917,6 +927,11 @@ public final class ScreenMagnifier implements EventStreamTransformation { mHandler.obtainMessage(MESSAGE_ON_ROTATION_CHANGED, rotation, 0) .sendToTarget(); } + + @Override + public void onWindowLayersChanged(int displayId) throws RemoteException { + mHandler.sendEmptyMessage(MESSAGE_ON_WINDOW_LAYERS_CHANGED); + } }; try { @@ -1192,6 +1207,9 @@ public final class ScreenMagnifier implements EventStreamTransformation { final int rotation = message.arg1; handleOnRotationChanged(rotation); } break; + case MESSAGE_ON_WINDOW_LAYERS_CHANGED: { + mViewport.recomputeBounds(mMagnificationController.isMagnifying()); + } break; default: { throw new IllegalArgumentException("Unknown message: " + action); } diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index 0a4252813188..93896af4b58b 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -305,6 +305,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { DisplayDevice device = mDisplayDevices.get(i); device.blankLocked(); } + + scheduleTraversalLocked(false); } } } @@ -322,6 +324,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { DisplayDevice device = mDisplayDevices.get(i); device.unblankLocked(); } + + scheduleTraversalLocked(false); } } } @@ -755,7 +759,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { + device.getDisplayDeviceInfoLocked()); return; } else { - display.configureDisplayInTransactionLocked(device); + boolean isBlanked = (mAllDisplayBlankStateFromPowerManager + == DISPLAY_BLANK_STATE_BLANKED); + display.configureDisplayInTransactionLocked(device, isBlanked); } // Update the viewports if needed. diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java index c4b749c3e90b..680662e538a8 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -55,6 +55,10 @@ import libcore.util.Objects; final class LogicalDisplay { private final DisplayInfo mBaseDisplayInfo = new DisplayInfo(); + // The layer stack we use when the display has been blanked to prevent any + // of its content from appearing. + private static final int BLANK_LAYER_STACK = -1; + private final int mDisplayId; private final int mLayerStack; private DisplayInfo mOverrideDisplayInfo; // set by the window manager @@ -217,13 +221,15 @@ final class LogicalDisplay { * where the display is being mirrored. * * @param device The display device to modify. + * @param isBlanked True if the device is being blanked. */ - public void configureDisplayInTransactionLocked(DisplayDevice device) { + public void configureDisplayInTransactionLocked(DisplayDevice device, + boolean isBlanked) { final DisplayInfo displayInfo = getDisplayInfoLocked(); final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked(); // Set the layer stack. - device.setLayerStackInTransactionLocked(mLayerStack); + device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack); // Set the viewport. // This is the area of the logical display that we intend to show on the diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index c3418727e338..fa450ae55bee 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -265,7 +265,7 @@ public class WindowManagerService extends IWindowManager.Stub static final int DEFAULT_FADE_IN_OUT_DURATION = 400; /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */ - static final int WINDOW_FREEZE_TIMEOUT_DURATION = 3000; + static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000; /** * If true, the window manager will do its own custom freezing and general @@ -6569,6 +6569,36 @@ public class WindowManagerService extends IWindowManager.Stub } } + private void scheduleNotifyWindowLayersChangedIfNeededLocked(DisplayContent displayContent) { + if (displayContent.mDisplayContentChangeListeners != null + && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) { + mH.obtainMessage(H.NOTIFY_WINDOW_LAYERS_CHANGED, displayContent) .sendToTarget(); + } + } + + private void handleNotifyWindowLayersChanged(DisplayContent displayContent) { + RemoteCallbackList<IDisplayContentChangeListener> callbacks = null; + synchronized (mWindowMap) { + callbacks = displayContent.mDisplayContentChangeListeners; + if (callbacks == null) { + return; + } + } + try { + final int watcherCount = callbacks.beginBroadcast(); + for (int i = 0; i < watcherCount; i++) { + try { + callbacks.getBroadcastItem(i).onWindowLayersChanged( + displayContent.getDisplayId()); + } catch (RemoteException re) { + /* ignore */ + } + } + } finally { + callbacks.finishBroadcast(); + } + } + public void addWindowChangeListener(WindowChangeListener listener) { synchronized(mWindowMap) { mWindowChangeListeners.add(listener); @@ -7215,12 +7245,13 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NOTIFY_ROTATION_CHANGED = 28; public static final int NOTIFY_WINDOW_TRANSITION = 29; public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30; + public static final int NOTIFY_WINDOW_LAYERS_CHANGED = 31; - public static final int DO_DISPLAY_ADDED = 31; - public static final int DO_DISPLAY_REMOVED = 32; - public static final int DO_DISPLAY_CHANGED = 33; + public static final int DO_DISPLAY_ADDED = 32; + public static final int DO_DISPLAY_REMOVED = 33; + public static final int DO_DISPLAY_CHANGED = 34; - public static final int CLIENT_FREEZE_TIMEOUT = 34; + public static final int CLIENT_FREEZE_TIMEOUT = 35; public static final int ANIMATOR_WHAT_OFFSET = 100000; public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1; @@ -7692,6 +7723,12 @@ public class WindowManagerService extends IWindowManager.Stub break; } + case NOTIFY_WINDOW_LAYERS_CHANGED: { + DisplayContent displayContent = (DisplayContent) msg.obj; + handleNotifyWindowLayersChanged(displayContent); + break; + } + case DO_DISPLAY_ADDED: synchronized (mWindowMap) { handleDisplayAddedLocked(msg.arg1); @@ -8068,6 +8105,8 @@ public class WindowManagerService extends IWindowManager.Stub Slog.v(TAG, "Assigning layers", here); } + boolean anyLayerChanged = false; + for (i=0; i<N; i++) { final WindowState w = windows.get(i); final WindowStateAnimator winAnimator = w.mWinAnimator; @@ -8083,6 +8122,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (w.mLayer != oldLayer) { layerChanged = true; + anyLayerChanged = true; } oldLayer = winAnimator.mAnimLayer; if (w.mTargetAppToken != null) { @@ -8101,6 +8141,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (winAnimator.mAnimLayer != oldLayer) { layerChanged = true; + anyLayerChanged = true; } if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) { // Force an animation pass just to update the mDimAnimator layer. @@ -8115,10 +8156,22 @@ public class WindowManagerService extends IWindowManager.Stub //System.out.println( // "Assigned layer " + curLayer + " to " + w.mClient.asBinder()); } + + if (anyLayerChanged) { + scheduleNotifyWindowLayersChangedIfNeededLocked(getDefaultDisplayContentLocked()); + } } - private boolean mInLayout = false; private final void performLayoutAndPlaceSurfacesLocked() { + do { + mTraversalScheduled = false; + performLayoutAndPlaceSurfacesLockedLoop(); + mH.removeMessages(H.DO_TRAVERSAL); + } while (mTraversalScheduled); + } + + private boolean mInLayout = false; + private final void performLayoutAndPlaceSurfacesLockedLoop() { if (mInLayout) { if (DEBUG) { throw new RuntimeException("Recursive call!"); diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index feb29b15e337..c195f4578d8b 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -1038,18 +1038,26 @@ final class WindowState implements WindowManagerPolicy.WindowState { } boolean isHiddenFromUserLocked() { - // Save some cycles by not calling getDisplayInfo unless it is an application - // window intended for all users. - if (mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW - && mAppToken != null && mAppToken.showWhenLocked) { - final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); - if (isFullscreen(displayInfo.appWidth, displayInfo.appHeight)) { + // Attached windows are evaluated based on the window that they are attached to. + WindowState win = this; + while (win.mAttachedWindow != null) { + win = win.mAttachedWindow; + } + if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW + && win.mAppToken != null && win.mAppToken.showWhenLocked) { + // Save some cycles by not calling getDisplayInfo unless it is an application + // window intended for all users. + final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo(); + if (win.mFrame.left <= 0 && win.mFrame.top <= 0 + && win.mFrame.right >= displayInfo.appWidth + && win.mFrame.bottom >= displayInfo.appHeight) { // Is a fullscreen window, like the clock alarm. Show to everyone. return false; } } - return mShowToOwnerOnly && UserHandle.getUserId(mOwnerUid) != mService.mCurrentUserId; + return win.mShowToOwnerOnly + && UserHandle.getUserId(win.mOwnerUid) != mService.mCurrentUserId; } private static void applyInsets(Region outRegion, Rect frame, Rect inset) { diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 4cb409d13220..9118aea1f575 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -33,6 +33,15 @@ <meta-data android:name="android.graphics.renderThread" android:value="true" /> <activity + android:name="MipMapActivity" + android:label="_MipMap"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="PathOffsetActivity" android:label="_PathOffset"> <intent-filter> diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg Binary files differnew file mode 100644 index 000000000000..7f047b1098e7 --- /dev/null +++ b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java index 8cc224651836..854dd69a8646 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java @@ -68,9 +68,16 @@ public class BitmapMeshActivity extends Activity { super.onDraw(canvas); canvas.drawARGB(255, 255, 255, 255); + canvas.translate(100, 100); canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, null, 0, null); + canvas.save(); + canvas.translate(0, 400); + canvas.clipRect(0.0f, 0.0f, 80.0f, 80.0f); + canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, null, 0, null); + canvas.restore(); + canvas.translate(400, 0); canvas.drawBitmapMesh(mBitmap1, 3, 3, mVertices, 0, mColors, 0, null); } diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java new file mode 100644 index 000000000000..1034649b6cb2 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class MipMapActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final BitmapsView view = new BitmapsView(this); + setContentView(view); + } + + static class BitmapsView extends View { + private Paint mBitmapPaint; + private final Bitmap mBitmap1; + private final Bitmap mBitmap2; + + BitmapsView(Context c) { + super(c); + + mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo); + mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo); + + mBitmap1.setHasMipMap(true); + + mBitmapPaint = new Paint(); + mBitmapPaint.setFilterBitmap(true); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.save(); + canvas.scale(0.3f, 0.3f); + canvas.drawBitmap(mBitmap1, 0, 0, mBitmapPaint); + canvas.restore(); + + canvas.save(); + canvas.translate(mBitmap1.getWidth() * 0.3f + 96.0f, 0.0f); + canvas.scale(0.3f, 0.3f); + canvas.drawBitmap(mBitmap2, 0, 0, mBitmapPaint); + canvas.restore(); + } + } +} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index e913d10c52b4..b871cdca9f5a 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1983,7 +1983,9 @@ public class WifiManager { protected void finalize() throws Throwable { try { - mHandler.getLooper().quit(); + if (mHandler != null && mHandler.getLooper() != null) { + mHandler.getLooper().quit(); + } } finally { super.finalize(); } |