diff options
Diffstat (limited to 'core/java')
19 files changed, 421 insertions, 164 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 389d485626be..f5849c24e59a 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -818,18 +818,6 @@ public class Activity extends ContextThemeWrapper return mWindow != null ? mWindow.getCurrentFocus() : null; } - @Override - public int getWallpaperDesiredMinimumWidth() { - int width = super.getWallpaperDesiredMinimumWidth(); - return width <= 0 ? getWindowManager().getDefaultDisplay().getWidth() : width; - } - - @Override - public int getWallpaperDesiredMinimumHeight() { - int height = super.getWallpaperDesiredMinimumHeight(); - return height <= 0 ? getWindowManager().getDefaultDisplay().getHeight() : height; - } - /** * Called when the activity is starting. This is where most initialization * should go: calling {@link #setContentView(int)} to inflate the diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java index 55368d623708..0c034cff9d4a 100644 --- a/core/java/android/app/backup/WallpaperBackupHelper.java +++ b/core/java/android/app/backup/WallpaperBackupHelper.java @@ -19,6 +19,7 @@ package android.app.backup; import android.app.WallpaperManager; import android.content.Context; import android.graphics.BitmapFactory; +import android.graphics.Point; import android.os.ParcelFileDescriptor; import android.util.Slog; import android.view.Display; @@ -70,8 +71,10 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu if (mDesiredMinWidth <= 0 || mDesiredMinHeight <= 0) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display d = wm.getDefaultDisplay(); - mDesiredMinWidth = d.getWidth(); - mDesiredMinHeight = d.getHeight(); + Point size = new Point(); + d.getSize(size); + mDesiredMinWidth = size.x; + mDesiredMinHeight = size.y; } if (DEBUG) { diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index ad48786ee596..93b34290e7b7 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -303,9 +303,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration public String toString() { StringBuilder sb = new StringBuilder(128); - sb.append("{ fnt="); + sb.append("{"); sb.append(fontScale); - sb.append(" imsi="); + sb.append("x imsi="); sb.append(mcc); sb.append("/"); sb.append(mnc); diff --git a/core/java/android/text/Selection.java b/core/java/android/text/Selection.java index b18570a8b027..679e2ccfa91f 100644 --- a/core/java/android/text/Selection.java +++ b/core/java/android/text/Selection.java @@ -16,10 +16,7 @@ package android.text; -import android.util.Log; - import java.text.BreakIterator; -import java.text.CharacterIterator; /** diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java index b25ba8d31a64..d432deef44bb 100644 --- a/core/java/android/text/method/ArrowKeyMovementMethod.java +++ b/core/java/android/text/method/ArrowKeyMovementMethod.java @@ -17,23 +17,14 @@ package android.text.method; import android.graphics.Rect; -import android.text.CharSequenceIterator; -import android.text.Editable; import android.text.Layout; import android.text.Selection; import android.text.Spannable; -import android.text.Spanned; -import android.text.TextWatcher; -import android.util.Log; -import android.util.MathUtils; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; -import java.text.BreakIterator; -import java.text.CharacterIterator; - /** * A movement method that provides cursor movement and selection. * Supports displaying the context menu on DPad Center. @@ -332,102 +323,6 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme return sInstance; } - /** - * Walks through cursor positions at word boundaries. Internally uses - * {@link BreakIterator#getWordInstance()}, and caches {@link CharSequence} - * for performance reasons. - */ - private static class WordIterator implements Selection.PositionIterator { - private CharSequence mCurrent; - private boolean mCurrentDirty = false; - - private BreakIterator mIterator; - - private TextWatcher mWatcher = new TextWatcher() { - /** {@inheritDoc} */ - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - // ignored - } - - /** {@inheritDoc} */ - public void onTextChanged(CharSequence s, int start, int before, int count) { - mCurrentDirty = true; - } - - /** {@inheritDoc} */ - public void afterTextChanged(Editable s) { - // ignored - } - }; - - public void setCharSequence(CharSequence incoming) { - if (mIterator == null) { - mIterator = BreakIterator.getWordInstance(); - } - - // when incoming is different object, move listeners to new sequence - // and mark as dirty so we reload contents. - if (mCurrent != incoming) { - if (mCurrent instanceof Editable) { - ((Editable) mCurrent).removeSpan(mWatcher); - } - - if (incoming instanceof Editable) { - ((Editable) incoming).setSpan( - mWatcher, 0, incoming.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); - } - - mCurrent = incoming; - mCurrentDirty = true; - } - - if (mCurrentDirty) { - final CharacterIterator charIterator = new CharSequenceIterator(mCurrent); - mIterator.setText(charIterator); - - mCurrentDirty = false; - } - } - - private boolean isValidOffset(int offset) { - return offset >= 0 && offset <= mCurrent.length(); - } - - private boolean isLetterOrDigit(int offset) { - if (isValidOffset(offset)) { - return Character.isLetterOrDigit(mCurrent.charAt(offset)); - } else { - return false; - } - } - - /** {@inheritDoc} */ - public int preceding(int offset) { - // always round cursor index into valid string index - offset = MathUtils.constrain(offset, 0, mCurrent.length()); - - do { - offset = mIterator.preceding(offset); - if (isLetterOrDigit(offset)) break; - } while (isValidOffset(offset)); - - return offset; - } - - /** {@inheritDoc} */ - public int following(int offset) { - // always round cursor index into valid string index - offset = MathUtils.constrain(offset, 0, mCurrent.length()); - - do { - offset = mIterator.following(offset); - if (isLetterOrDigit(offset - 1)) break; - } while (isValidOffset(offset)); - - return offset; - } - } - private WordIterator mWordIterator = new WordIterator(); private static final Object LAST_TAP_DOWN = new Object(); diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java new file mode 100644 index 000000000000..b250414bf78a --- /dev/null +++ b/core/java/android/text/method/WordIterator.java @@ -0,0 +1,220 @@ + +/* + * Copyright (C) 2011 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.text.method; + +import android.text.CharSequenceIterator; +import android.text.Editable; +import android.text.Selection; +import android.text.Spanned; +import android.text.TextWatcher; + +import java.text.BreakIterator; +import java.text.CharacterIterator; +import java.util.Locale; + +/** + * Walks through cursor positions at word boundaries. Internally uses + * {@link BreakIterator#getWordInstance()}, and caches {@link CharSequence} + * for performance reasons. + * + * Also provides methods to determine word boundaries. + * {@hide} + */ +public class WordIterator implements Selection.PositionIterator { + private CharSequence mCurrent; + private boolean mCurrentDirty = false; + + private BreakIterator mIterator; + + /** + * Constructs a WordIterator using the default locale. + */ + public WordIterator() { + this(Locale.getDefault()); + } + + /** + * Constructs a new WordIterator for the specified locale. + * @param locale The locale to be used when analysing the text. + */ + public WordIterator(Locale locale) { + mIterator = BreakIterator.getWordInstance(locale); + } + + private final TextWatcher mWatcher = new TextWatcher() { + /** {@inheritDoc} */ + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // ignored + } + + /** {@inheritDoc} */ + public void onTextChanged(CharSequence s, int start, int before, int count) { + mCurrentDirty = true; + } + + /** {@inheritDoc} */ + public void afterTextChanged(Editable s) { + // ignored + } + }; + + public void setCharSequence(CharSequence incoming) { + // When incoming is different object, move listeners to new sequence + // and mark as dirty so we reload contents. + if (mCurrent != incoming) { + if (mCurrent instanceof Editable) { + ((Editable) mCurrent).removeSpan(mWatcher); + } + + if (incoming instanceof Editable) { + ((Editable) incoming).setSpan( + mWatcher, 0, incoming.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); + } + + mCurrent = incoming; + mCurrentDirty = true; + } + + if (mCurrentDirty) { + final CharacterIterator charIterator = new CharSequenceIterator(mCurrent); + mIterator.setText(charIterator); + + mCurrentDirty = false; + } + } + + /** {@inheritDoc} */ + public int preceding(int offset) { + do { + offset = mIterator.preceding(offset); + if (offset == BreakIterator.DONE || isOnLetterOrDigit(offset)) { + break; + } + } while (true); + + return offset; + } + + /** {@inheritDoc} */ + public int following(int offset) { + do { + offset = mIterator.following(offset); + if (offset == BreakIterator.DONE || isAfterLetterOrDigit(offset)) { + break; + } + } while (true); + + return offset; + } + + /** If <code>offset</code> is within a word, returns the index of the first character of that + * word, otherwise returns BreakIterator.DONE. + * + * The offsets that are considered to be part of a word are the indexes of its characters, + * <i>as well as</i> the index of its last character plus one. + * If offset is the index of a low surrogate character, BreakIterator.DONE will be returned. + * + * Valid range for offset is [0..textLength] (note the inclusive upper bound). + * The returned value is within [0..offset] or BreakIterator.DONE. + * + * @throws IllegalArgumentException is offset is not valid. + */ + public int getBeginning(int offset) { + checkOffsetIsValid(offset); + + if (isOnLetterOrDigit(offset)) { + if (mIterator.isBoundary(offset)) { + return offset; + } else { + return mIterator.preceding(offset); + } + } else { + if (isAfterLetterOrDigit(offset)) { + return mIterator.preceding(offset); + } + } + return BreakIterator.DONE; + } + + /** If <code>offset</code> is within a word, returns the index of the last character of that + * word plus one, otherwise returns BreakIterator.DONE. + * + * The offsets that are considered to be part of a word are the indexes of its characters, + * <i>as well as</i> the index of its last character plus one. + * If offset is the index of a low surrogate character, BreakIterator.DONE will be returned. + * + * Valid range for offset is [0..textLength] (note the inclusive upper bound). + * The returned value is within [offset..textLength] or BreakIterator.DONE. + * + * @throws IllegalArgumentException is offset is not valid. + */ + public int getEnd(int offset) { + checkOffsetIsValid(offset); + + if (isAfterLetterOrDigit(offset)) { + if (mIterator.isBoundary(offset)) { + return offset; + } else { + return mIterator.following(offset); + } + } else { + if (isOnLetterOrDigit(offset)) { + return mIterator.following(offset); + } + } + return BreakIterator.DONE; + } + + private boolean isAfterLetterOrDigit(int offset) { + if (offset - 1 >= 0) { + final char previousChar = mCurrent.charAt(offset - 1); + if (Character.isLetterOrDigit(previousChar)) return true; + if (offset - 2 >= 0) { + final char previousPreviousChar = mCurrent.charAt(offset - 2); + if (Character.isSurrogatePair(previousPreviousChar, previousChar)) { + final int codePoint = Character.toCodePoint(previousPreviousChar, previousChar); + return Character.isLetterOrDigit(codePoint); + } + } + } + return false; + } + + private boolean isOnLetterOrDigit(int offset) { + final int length = mCurrent.length(); + if (offset < length) { + final char currentChar = mCurrent.charAt(offset); + if (Character.isLetterOrDigit(currentChar)) return true; + if (offset + 1 < length) { + final char nextChar = mCurrent.charAt(offset + 1); + if (Character.isSurrogatePair(currentChar, nextChar)) { + final int codePoint = Character.toCodePoint(currentChar, nextChar); + return Character.isLetterOrDigit(codePoint); + } + } + } + return false; + } + + private void checkOffsetIsValid(int offset) { + if (offset < 0 || offset > mCurrent.length()) { + final String message = "Valid range is [0, " + mCurrent.length() + "]"; + throw new IllegalArgumentException(message); + } + } +} diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java index 563c50089016..132b5953fa68 100644 --- a/core/java/android/util/JsonReader.java +++ b/core/java/android/util/JsonReader.java @@ -16,12 +16,13 @@ package android.util; +import java.io.Closeable; import java.io.EOFException; import java.io.IOException; import java.io.Reader; -import java.io.Closeable; import java.util.ArrayList; import java.util.List; +import libcore.internal.StringPool; /** * Reads a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>) @@ -177,6 +178,8 @@ public final class JsonReader implements Closeable { private static final String TRUE = "true"; private static final String FALSE = "false"; + private final StringPool stringPool = new StringPool(); + /** The input JSON. */ private final Reader in; @@ -836,7 +839,7 @@ public final class JsonReader implements Closeable { if (skipping) { return "skipped!"; } else if (builder == null) { - return new String(buffer, start, pos - start - 1); + return stringPool.get(buffer, start, pos - start - 1); } else { builder.append(buffer, start, pos - start - 1); return builder.toString(); @@ -934,7 +937,7 @@ public final class JsonReader implements Closeable { } else if (skipping) { result = "skipped!"; } else if (builder == null) { - result = new String(buffer, pos, i); + result = stringPool.get(buffer, pos, i); } else { builder.append(buffer, pos, i); result = builder.toString(); @@ -968,7 +971,7 @@ public final class JsonReader implements Closeable { if (pos + 4 > limit && !fillBuffer(4)) { throw syntaxError("Unterminated escape sequence"); } - String hex = new String(buffer, pos, 4); + String hex = stringPool.get(buffer, pos, 4); pos += 4; return (char) Integer.parseInt(hex, 16); @@ -1040,7 +1043,7 @@ public final class JsonReader implements Closeable { value = FALSE; return JsonToken.BOOLEAN; } else { - value = new String(buffer, valuePos, valueLength); + value = stringPool.get(buffer, valuePos, valueLength); return decodeNumber(buffer, valuePos, valueLength); } } diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 126f409d1dab..8e839c09b1d2 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -16,10 +16,15 @@ package android.view; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; import android.util.DisplayMetrics; +import android.util.Slog; -public class Display -{ +public class Display { /** * Specify the default Display */ @@ -35,10 +40,10 @@ public class Display Display(int display) { // initalize the statics when this class is first instansiated. This is // done here instead of in the static block because Zygote - synchronized (mStaticInit) { - if (!mInitialized) { + synchronized (sStaticInit) { + if (!sInitialized) { nativeClassInit(); - mInitialized = true; + sInitialized = true; } } mDisplay = display; @@ -60,29 +65,92 @@ public class Display native static int getDisplayCount(); /** - * Returns the raw width of the display, in pixels. Note that this + * Returns the raw size of the display, in pixels. Note that this * should <em>not</em> generally be used for computing layouts, since * a device will typically have screen decoration (such as a status bar) * along the edges of the display that reduce the amount of application * space available from the raw size returned here. This value is * adjusted for you based on the current rotation of the display. */ - native public int getWidth(); + public void getSize(Point outSize) { + try { + IWindowManager wm = getWindowManager(); + if (wm != null) { + wm.getDisplaySize(outSize); + } else { + // This is just for boot-strapping, initializing the + // system process before the window manager is up. + outSize.y = getRealHeight(); + } + } catch (RemoteException e) { + Slog.w("Display", "Unable to get display size", e); + } + } /** - * Returns the raw height of the display, in pixels. Note that this - * should <em>not</em> generally be used for computing layouts, since - * a device will typically have screen decoration (such as a status bar) - * along the edges of the display that reduce the amount of application - * space available from the raw size returned here. This value is - * adjusted for you based on the current rotation of the display. + * This is just easier for some parts of the framework. */ - native public int getHeight(); + public void getRectSize(Rect outSize) { + synchronized (mTmpPoint) { + getSize(mTmpPoint); + outSize.set(0, 0, mTmpPoint.x, mTmpPoint.y); + } + } - /** @hide special for when we are faking the screen size. */ + /** + * Return the maximum screen size dimension that will happen. This is + * mostly for wallpapers. + * @hide + */ + public int getMaximumSizeDimension() { + try { + IWindowManager wm = getWindowManager(); + return wm.getMaximumSizeDimension(); + } catch (RemoteException e) { + Slog.w("Display", "Unable to get display maximum size dimension", e); + return 0; + } + } + + /** + * @deprecated Use {@link #getSize(Point)} instead. + */ + @Deprecated + public int getWidth() { + synchronized (mTmpPoint) { + long now = SystemClock.uptimeMillis(); + if (now > (mLastGetTime+20)) { + getSize(mTmpPoint); + mLastGetTime = now; + } + return mTmpPoint.x; + } + } + + /** + * @deprecated Use {@link #getSize(Point)} instead. + */ + @Deprecated + public int getHeight() { + synchronized (mTmpPoint) { + long now = SystemClock.uptimeMillis(); + if (now > (mLastGetTime+20)) { + getSize(mTmpPoint); + mLastGetTime = now; + } + return mTmpPoint.y; + } + } + + /** @hide Returns the actual screen size, not including any decor. */ native public int getRealWidth(); - /** @hide special for when we are faking the screen size. */ + /** @hide Returns the actual screen size, not including any decor. */ native public int getRealHeight(); + + /** @hide special for when we are faking the screen size. */ + native public int getRawWidth(); + /** @hide special for when we are faking the screen size. */ + native public int getRawHeight(); /** * Returns the rotation of the screen from its "natural" orientation. @@ -132,8 +200,27 @@ public class Display * @param outMetrics */ public void getMetrics(DisplayMetrics outMetrics) { - outMetrics.widthPixels = getWidth(); - outMetrics.heightPixels = getHeight(); + synchronized (mTmpPoint) { + getSize(mTmpPoint); + outMetrics.widthPixels = mTmpPoint.x; + outMetrics.heightPixels = mTmpPoint.y; + } + getNonSizeMetrics(outMetrics); + } + + /** + * Initialize a DisplayMetrics object from this display's data. + * + * @param outMetrics + * @hide + */ + public void getRealMetrics(DisplayMetrics outMetrics) { + outMetrics.widthPixels = getRealWidth(); + outMetrics.heightPixels = getRealHeight(); + getNonSizeMetrics(outMetrics); + } + + private void getNonSizeMetrics(DisplayMetrics outMetrics) { outMetrics.density = mDensity; outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f); outMetrics.scaledDensity= outMetrics.density; @@ -141,6 +228,16 @@ public class Display outMetrics.ydpi = mDpiY; } + static IWindowManager getWindowManager() { + synchronized (sStaticInit) { + if (sWindowManager == null) { + sWindowManager = IWindowManager.Stub.asInterface( + ServiceManager.getService("window")); + } + return sWindowManager; + } + } + /* * We use a class initializer to allow the native code to cache some * field offsets. @@ -157,8 +254,12 @@ public class Display private float mDpiX; private float mDpiY; - private static final Object mStaticInit = new Object(); - private static boolean mInitialized = false; + private final Point mTmpPoint = new Point(); + private float mLastGetTime; + + private static final Object sStaticInit = new Object(); + private static boolean sInitialized = false; + private static IWindowManager sWindowManager; /** * Returns a display object which uses the metric's width/height instead. diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index dd8242a6fef1..0be02a665bff 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -21,6 +21,7 @@ import com.android.internal.view.IInputMethodClient; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Point; import android.view.IApplicationToken; import android.view.IOnKeyguardExitResult; import android.view.IRotationWatcher; @@ -52,6 +53,9 @@ interface IWindowManager in IInputContext inputContext); boolean inputMethodClientHasFocus(IInputMethodClient client); + void getDisplaySize(out Point size); + int getMaximumSizeDimension(); + // These can only be called when injecting events to your own window, // or by holding the INJECT_EVENTS permission. These methods may block // until pending input events are finished being dispatched even when 'sync' is false. diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 98d4eb9a8f0c..8cb68f90ec45 100755 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -290,7 +290,7 @@ public final class InputDevice implements Parcelable { * @return The input device or null if not found. */ public static InputDevice getDevice(int id) { - IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); + IWindowManager wm = Display.getWindowManager(); try { return wm.getInputDevice(id); } catch (RemoteException ex) { @@ -304,7 +304,7 @@ public final class InputDevice implements Parcelable { * @return The input device ids. */ public static int[] getDeviceIds() { - IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); + IWindowManager wm = Display.getWindowManager(); try { return wm.getInputDeviceIds(); } catch (RemoteException ex) { diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index 3ff7fcd6d778..885a75f64168 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -527,7 +527,7 @@ public class KeyCharacterMap { */ public static boolean[] deviceHasKeys(int[] keyCodes) { boolean[] ret = new boolean[keyCodes.length]; - IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); + IWindowManager wm = Display.getWindowManager(); try { wm.hasKeys(keyCodes, ret); } catch (RemoteException e) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index fe8af1974deb..4a6289285d41 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4992,7 +4992,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility return; } Display d = WindowManagerImpl.getDefault().getDefaultDisplay(); - outRect.set(0, 0, d.getWidth(), d.getHeight()); + d.getRectSize(outRect); } /** diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 1a6bae710f45..4104b070f4a1 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -263,9 +263,8 @@ public final class ViewRoot extends Handler implements ViewParent, if (!mInitialized) { try { InputMethodManager imm = InputMethodManager.getInstance(mainLooper); - sWindowSession = IWindowManager.Stub.asInterface( - ServiceManager.getService("window")) - .openSession(imm.getClient(), imm.getInputContext()); + sWindowSession = Display.getWindowManager().openSession( + imm.getClient(), imm.getInputContext()); mInitialized = true; } catch (RemoteException e) { } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 9d00d023514d..3d19380d5959 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -396,6 +396,12 @@ public interface WindowManagerPolicy { LocalPowerManager powerManager); /** + * Called by window manager once it has the initial, default native + * display dimensions. + */ + public void setInitialDisplaySize(int width, int height); + + /** * Check permissions when adding a window. * * @param attrs The window's LayoutParams. @@ -810,6 +816,13 @@ public interface WindowManagerPolicy { boolean displayEnabled); /** + * Return the currently locked screen rotation, if any. Return + * Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_180, or + * Surface.ROTATION_270 if locked; return -1 if not locked. + */ + public int getLockedRotationLw(); + + /** * Called when the system is mostly done booting to determine whether * the system should go into safe mode. */ diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index 16d5539b8cdf..96520858fe95 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -861,7 +861,7 @@ public class ActionBarImpl extends ActionBar { @Override public void setIcon(int resId) { - mActionView.setIcon(mContext.getResources().getDrawable(resId)); + mActionView.setIcon(resId); } @Override @@ -871,7 +871,7 @@ public class ActionBarImpl extends ActionBar { @Override public void setLogo(int resId) { - mActionView.setLogo(mContext.getResources().getDrawable(resId)); + mActionView.setLogo(resId); } @Override diff --git a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java index 71511c62090a..16f51fd20ae0 100644 --- a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java @@ -104,6 +104,10 @@ public abstract class BaseMenuPresenter implements MenuPresenter { * @param childIndex Index within the parent to insert at */ protected void addItemView(View itemView, int childIndex) { + final ViewGroup currentParent = (ViewGroup) itemView.getParent(); + if (currentParent != null) { + currentParent.removeView(itemView); + } ((ViewGroup) mMenuView).addView(itemView, childIndex); } diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index b34814223d97..7fba5cac2aee 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -814,8 +814,10 @@ public class MenuBuilder implements Menu { * many menu operations are going to be performed as a batch. */ public void stopDispatchingItemsChanged() { - mPreventDispatchingItemsChanged = true; - mItemsChangedWhileDispatchPrevented = false; + if (!mPreventDispatchingItemsChanged) { + mPreventDispatchingItemsChanged = true; + mItemsChangedWhileDispatchPrevented = false; + } } public void startDispatchingItemsChanged() { diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index 42ef916c995c..c6d386d1fa48 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -523,7 +523,9 @@ public final class MenuItemImpl implements MenuItem { } public boolean showsTextAsAction() { - return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT; + return (mShowAsAction & SHOW_AS_ACTION_WITH_TEXT) == SHOW_AS_ACTION_WITH_TEXT && + mMenu.getContext().getResources().getBoolean( + com.android.internal.R.bool.allow_action_menu_item_text_with_icon); } public void setShowAsAction(int actionEnum) { diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 74a6ae7724ac..587d67895f9d 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -30,11 +30,13 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.util.Log; import android.view.ActionMode; import android.view.Gravity; @@ -85,7 +87,6 @@ public class ActionBarView extends ViewGroup { private CharSequence mSubtitle; private Drawable mIcon; private Drawable mLogo; - private Drawable mDivider; private View mHomeLayout; private View mHomeAsUpView; @@ -211,8 +212,6 @@ public class ActionBarView extends ViewGroup { mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0); - mDivider = a.getDrawable(R.styleable.ActionBar_divider); - a.recycle(); mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle); @@ -434,6 +433,10 @@ public class ActionBarView extends ViewGroup { } } + public void setIcon(int resId) { + setIcon(mContext.getResources().getDrawableForDensity(resId, getPreferredIconDensity())); + } + public void setLogo(Drawable logo) { mLogo = logo; if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { @@ -441,6 +444,29 @@ public class ActionBarView extends ViewGroup { } } + public void setLogo(int resId) { + mContext.getResources().getDrawable(resId); + } + + /** + * @return Drawable density to load that will best fit the available height. + */ + private int getPreferredIconDensity() { + final Resources res = mContext.getResources(); + final int availableHeight = getLayoutParams().height - + mIconView.getPaddingTop() - mIconView.getPaddingBottom(); + int iconSize = res.getDimensionPixelSize(android.R.dimen.app_icon_size); + + if (iconSize * DisplayMetrics.DENSITY_LOW > availableHeight) { + return DisplayMetrics.DENSITY_LOW; + } else if (iconSize * DisplayMetrics.DENSITY_MEDIUM > availableHeight) { + return DisplayMetrics.DENSITY_MEDIUM; + } else if (iconSize * DisplayMetrics.DENSITY_HIGH > availableHeight) { + return DisplayMetrics.DENSITY_HIGH; + } + return DisplayMetrics.DENSITY_XHIGH; + } + public void setNavigationMode(int mode) { final int oldMode = mNavigationMode; if (mode != oldMode) { |
