summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Activity.java12
-rw-r--r--core/java/android/app/backup/WallpaperBackupHelper.java7
-rw-r--r--core/java/android/content/res/Configuration.java4
-rw-r--r--core/java/android/text/Selection.java3
-rw-r--r--core/java/android/text/method/ArrowKeyMovementMethod.java105
-rw-r--r--core/java/android/text/method/WordIterator.java220
-rw-r--r--core/java/android/util/JsonReader.java13
-rw-r--r--core/java/android/view/Display.java141
-rw-r--r--core/java/android/view/IWindowManager.aidl4
-rwxr-xr-xcore/java/android/view/InputDevice.java4
-rw-r--r--core/java/android/view/KeyCharacterMap.java2
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/view/ViewRoot.java5
-rw-r--r--core/java/android/view/WindowManagerPolicy.java13
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java4
-rw-r--r--core/java/com/android/internal/view/menu/BaseMenuPresenter.java4
-rw-r--r--core/java/com/android/internal/view/menu/MenuBuilder.java6
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java4
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java32
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) {