diff options
48 files changed, 746 insertions, 592 deletions
diff --git a/Android.mk b/Android.mk index 91850d5af79d..be8c25b714a1 100644 --- a/Android.mk +++ b/Android.mk @@ -381,7 +381,7 @@ framework_docs_LOCAL_DROIDDOC_OPTIONS := \ -since ./frameworks/base/api/11.xml 11 \ -since ./frameworks/base/api/12.xml 12 \ -since ./frameworks/base/api/13.xml 13 \ - -since ./frameworks/base/api/current.txt ICS \ + -since ./frameworks/base/api/14.txt 14 \ -werror -hide 113 \ -overview $(LOCAL_PATH)/core/java/overview.html @@ -473,7 +473,7 @@ web_docs_sample_code_flags := \ ## SDK version identifiers used in the published docs # major[.minor] version for current SDK. (full releases only) -framework_docs_SDK_VERSION:=3.2 +framework_docs_SDK_VERSION:=4.0 # release version (ie "Release x") (full releases only) framework_docs_SDK_REL_ID:=1 diff --git a/api/14.txt b/api/14.txt index 45bb8823753f..9f2a6dfc3855 100644 --- a/api/14.txt +++ b/api/14.txt @@ -759,6 +759,7 @@ package android { field public static final int prompt = 16843131; // 0x101017b field public static final int propertyName = 16843489; // 0x10102e1 field public static final int protectionLevel = 16842761; // 0x1010009 + field public static final int publicKey = 16843686; // 0x10103a6 field public static final int queryActionMsg = 16843227; // 0x10101db field public static final int queryAfterZeroResults = 16843394; // 0x1010282 field public static final int queryHint = 16843608; // 0x1010358 @@ -4566,6 +4567,7 @@ package android.bluetooth { field public static final java.lang.String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE"; field public static final java.lang.String EXTRA_STATE = "android.bluetooth.profile.extra.STATE"; field public static final int HEADSET = 1; // 0x1 + field public static final int HEALTH = 3; // 0x3 field public static final int STATE_CONNECTED = 2; // 0x2 field public static final int STATE_CONNECTING = 1; // 0x1 field public static final int STATE_DISCONNECTED = 0; // 0x0 @@ -5454,6 +5456,7 @@ package android.content { field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; + field public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; field public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED"; field public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED"; field public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; @@ -6207,11 +6210,13 @@ package android.content.pm { method public abstract void setApplicationEnabledSetting(java.lang.String, int, int); method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int); method public abstract void setInstallerPackageName(java.lang.String, java.lang.String); + method public abstract void verifyPendingInstall(int, int); field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0 field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2 field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3 field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1 field public static final int DONT_KILL_APP = 1; // 0x1 + field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; @@ -6273,6 +6278,8 @@ package android.content.pm { field public static final int SIGNATURE_NO_MATCH = -3; // 0xfffffffd field public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; // 0xfffffffe field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc + field public static final int VERIFICATION_ALLOW = 1; // 0x1 + field public static final int VERIFICATION_REJECT = -1; // 0xffffffff } public static class PackageManager.NameNotFoundException extends android.util.AndroidException { @@ -19834,6 +19841,7 @@ package android.test.mock { method public void setApplicationEnabledSetting(java.lang.String, int, int); method public void setComponentEnabledSetting(android.content.ComponentName, int, int); method public void setInstallerPackageName(java.lang.String, java.lang.String); + method public void verifyPendingInstall(int, int); } public class MockResources extends android.content.res.Resources { diff --git a/api/current.txt b/api/current.txt index 45bb8823753f..9f2a6dfc3855 100644 --- a/api/current.txt +++ b/api/current.txt @@ -759,6 +759,7 @@ package android { field public static final int prompt = 16843131; // 0x101017b field public static final int propertyName = 16843489; // 0x10102e1 field public static final int protectionLevel = 16842761; // 0x1010009 + field public static final int publicKey = 16843686; // 0x10103a6 field public static final int queryActionMsg = 16843227; // 0x10101db field public static final int queryAfterZeroResults = 16843394; // 0x1010282 field public static final int queryHint = 16843608; // 0x1010358 @@ -4566,6 +4567,7 @@ package android.bluetooth { field public static final java.lang.String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE"; field public static final java.lang.String EXTRA_STATE = "android.bluetooth.profile.extra.STATE"; field public static final int HEADSET = 1; // 0x1 + field public static final int HEALTH = 3; // 0x3 field public static final int STATE_CONNECTED = 2; // 0x2 field public static final int STATE_CONNECTING = 1; // 0x1 field public static final int STATE_DISCONNECTED = 0; // 0x0 @@ -5454,6 +5456,7 @@ package android.content { field public static final java.lang.String ACTION_PACKAGE_FIRST_LAUNCH = "android.intent.action.PACKAGE_FIRST_LAUNCH"; field public static final java.lang.String ACTION_PACKAGE_FULLY_REMOVED = "android.intent.action.PACKAGE_FULLY_REMOVED"; field public static final deprecated java.lang.String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL"; + field public static final java.lang.String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; field public static final java.lang.String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED"; field public static final java.lang.String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED"; field public static final java.lang.String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED"; @@ -6207,11 +6210,13 @@ package android.content.pm { method public abstract void setApplicationEnabledSetting(java.lang.String, int, int); method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int); method public abstract void setInstallerPackageName(java.lang.String, java.lang.String); + method public abstract void verifyPendingInstall(int, int); field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0 field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2 field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3 field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1 field public static final int DONT_KILL_APP = 1; // 0x1 + field public static final java.lang.String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency"; field public static final java.lang.String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; field public static final java.lang.String FEATURE_CAMERA = "android.hardware.camera"; @@ -6273,6 +6278,8 @@ package android.content.pm { field public static final int SIGNATURE_NO_MATCH = -3; // 0xfffffffd field public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; // 0xfffffffe field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc + field public static final int VERIFICATION_ALLOW = 1; // 0x1 + field public static final int VERIFICATION_REJECT = -1; // 0xffffffff } public static class PackageManager.NameNotFoundException extends android.util.AndroidException { @@ -19834,6 +19841,7 @@ package android.test.mock { method public void setApplicationEnabledSetting(java.lang.String, int, int); method public void setComponentEnabledSetting(android.content.ComponentName, int, int); method public void setInstallerPackageName(java.lang.String, java.lang.String); + method public void verifyPendingInstall(int, int); } public class MockResources extends android.content.res.Resources { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index bd42e3413ca7..8ed7481cddd1 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -954,9 +954,9 @@ final class ApplicationPackageManager extends PackageManager { } @Override - public void verifyPendingInstall(int id, boolean verified, String failureMessage) { + public void verifyPendingInstall(int id, int response) { try { - mPM.verifyPendingInstall(id, verified, failureMessage); + mPM.verifyPendingInstall(id, response); } catch (RemoteException e) { // Should never happen! } diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index 58b386838799..f7ccfbd35fba 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -66,7 +66,6 @@ public interface BluetoothProfile { /** * Health Profile - * @hide */ public static final int HEALTH = 3; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index c7698bf17b72..72cf26acf6f8 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1535,8 +1535,6 @@ public class Intent implements Parcelable, Cloneable { * <p class="note"> * This is a protected intent that can only be sent by the system. * </p> - * - * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PACKAGE_NEEDS_VERIFICATION = "android.intent.action.PACKAGE_NEEDS_VERIFICATION"; diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 5e6e7686c174..a3bcc287e021 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -359,7 +359,7 @@ interface IPackageManager { int flags, in String installerPackageName, in Uri verificationURI, in ManifestDigest manifestDigest); - void verifyPendingInstall(int id, boolean verified, in String message); + void verifyPendingInstall(int id, int verificationCode); VerifierDeviceIdentity getVerifierDeviceIdentity(); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index dcb677617f2e..ef7e23345036 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -725,7 +725,22 @@ public abstract class PackageManager { public static final int MOVE_EXTERNAL_MEDIA = 0x00000002; /** + * Used as the {@code verificationCode} argument for + * {@link PackageManager#verifyPendingInstall} to indicate that the calling + * package verifier allows the installation to proceed. + */ + public static final int VERIFICATION_ALLOW = 1; + + /** + * Used as the {@code verificationCode} argument for + * {@link PackageManager#verifyPendingInstall} to indicate the calling + * package verifier does not vote to allow the installation to proceed. + */ + public static final int VERIFICATION_REJECT = -1; + + /** * Range of IDs allocated for a user. + * * @hide */ public static final int PER_USER_RANGE = 100000; @@ -1045,9 +1060,7 @@ public abstract class PackageManager { /** * Extra field name for the ID of a package pending verification. Passed to * a package verifier and is used to call back to - * {@link PackageManager#verifyPendingInstall(int, boolean)} - * - * @hide + * {@link PackageManager#verifyPendingInstall(int, int)} */ public static final String EXTRA_VERIFICATION_ID = "android.content.pm.extra.VERIFICATION_ID"; @@ -2156,16 +2169,17 @@ public abstract class PackageManager { /** * Allows a package listening to the * {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification - * broadcast} to respond to the package manager. + * broadcast} to respond to the package manager. The response must include + * the {@code verificationCode} which is one of + * {@link PackageManager#VERIFICATION_ALLOW} or + * {@link PackageManager#VERIFICATION_REJECT}. * * @param id pending package identifier as passed via the * {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra - * @param verified whether the package was verified as valid - * @param failureMessage if verification was false, this is the error - * message that may be shown to the user - * @hide + * @param verificationCode either {@link PackageManager#VERIFICATION_ALLOW} + * or {@link PackageManager#VERIFICATION_REJECT}. */ - public abstract void verifyPendingInstall(int id, boolean verified, String failureMessage); + public abstract void verifyPendingInstall(int id, int verificationCode); /** * Change the installer associated with a given package. There are limitations diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java index 10386f84671d..4fe54c0aa4dd 100644 --- a/core/java/android/inputmethodservice/Keyboard.java +++ b/core/java/android/inputmethodservice/Keyboard.java @@ -144,6 +144,8 @@ public class Keyboard { /** Number of key widths from current touch point to search for nearest keys. */ private static float SEARCH_DISTANCE = 1.8f; + private ArrayList<Row> rows = new ArrayList<Row>(); + /** * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. * Some of the key size defaults can be overridden per row from what the {@link Keyboard} @@ -164,6 +166,9 @@ public class Keyboard { public int defaultHorizontalGap; /** Vertical gap following this row. */ public int verticalGap; + + ArrayList<Key> mKeys = new ArrayList<Key>(); + /** * Edge flags for this row of keys. Possible values that can be assigned are * {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM} @@ -256,7 +261,7 @@ public class Keyboard { public CharSequence text; /** Popup characters */ public CharSequence popupCharacters; - + /** * Flags that specify the anchoring to edges of the keyboard for detecting touch events * that are just out of the boundary of the key. This is a bit mask of @@ -596,11 +601,44 @@ public class Keyboard { column++; x += key.width + key.gap; mKeys.add(key); + row.mKeys.add(key); if (x > mTotalWidth) { mTotalWidth = x; } } - mTotalHeight = y + mDefaultHeight; + mTotalHeight = y + mDefaultHeight; + rows.add(row); + } + + final void resize(int newWidth, int newHeight) { + int numRows = rows.size(); + for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) { + Row row = rows.get(rowIndex); + int numKeys = row.mKeys.size(); + int totalGap = 0; + int totalWidth = 0; + for (int keyIndex = 0; keyIndex < numKeys; ++keyIndex) { + Key key = row.mKeys.get(keyIndex); + if (keyIndex > 0) { + totalGap += key.gap; + } + totalWidth += key.width; + } + if (totalGap + totalWidth > newWidth) { + int x = 0; + float scaleFactor = (float)(newWidth - totalGap) / totalWidth; + for (int keyIndex = 0; keyIndex < numKeys; ++keyIndex) { + Key key = row.mKeys.get(keyIndex); + key.width *= scaleFactor; + key.x = x; + x += key.width + key.gap; + } + } + } + mTotalWidth = newWidth; + // TODO: This does not adjust the vertical placement according to the new size. + // The main problem in the previous code was horizontal placement/size, but we should + // also recalculate the vertical sizes/positions when we get this resize call. } public List<Key> getKeys() { @@ -749,7 +787,7 @@ public class Keyboard { Row currentRow = null; Resources res = context.getResources(); boolean skipRow = false; - + try { int event; while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) { @@ -759,6 +797,7 @@ public class Keyboard { inRow = true; x = 0; currentRow = createRowFromXml(res, parser); + rows.add(currentRow); skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode; if (skipRow) { skipToEndOfRow(parser); @@ -781,6 +820,7 @@ public class Keyboard { } else if (key.codes[0] == KEYCODE_ALT) { mModifierKeys.add(key); } + currentRow.mKeys.add(key); } else if (TAG_KEYBOARD.equals(tag)) { parseKeyboardAttributes(res, parser); } diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java index 05444f628ffe..1119c1eb1b31 100644 --- a/core/java/android/inputmethodservice/KeyboardView.java +++ b/core/java/android/inputmethodservice/KeyboardView.java @@ -376,6 +376,7 @@ public class KeyboardView extends View implements View.OnClickListener { initGestureDetector(); } + private void initGestureDetector() { mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { @Override @@ -615,6 +616,9 @@ public class KeyboardView extends View implements View.OnClickListener { @Override public void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); + if (mKeyboard != null) { + mKeyboard.resize(w, h); + } // Release the buffer, if any and it will be reallocated on the next draw mBuffer = null; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index bc5994e371de..bc05078906e6 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1882,6 +1882,11 @@ public final class Settings { /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. + * + * NOTE: Settings are backed up and restored in the order they appear + * in this array. If you have one setting depending on another, + * make sure that they are ordered appropriately. + * * @hide */ public static final String[] SETTINGS_TO_BACKUP = { @@ -4048,6 +4053,12 @@ public final class Settings { public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout"; /** + * This are the settings to be backed up. + * + * NOTE: Settings are backed up and restored in the order they appear + * in this array. If you have one setting depending on another, + * make sure that they are ordered appropriately. + * * @hide */ public static final String[] SETTINGS_TO_BACKUP = { @@ -4056,11 +4067,11 @@ public final class Settings { PARENTAL_CONTROL_ENABLED, PARENTAL_CONTROL_REDIRECT_URL, USB_MASS_STORAGE_ENABLED, - ACCESSIBILITY_ENABLED, ACCESSIBILITY_SCRIPT_INJECTION, BACKUP_AUTO_RESTORE, ENABLED_ACCESSIBILITY_SERVICES, TOUCH_EXPLORATION_ENABLED, + ACCESSIBILITY_ENABLED, TTS_USE_DEFAULTS, TTS_DEFAULT_RATE, TTS_DEFAULT_PITCH, diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java index 5601dc526c2f..ed976ab1d6b6 100644 --- a/core/java/android/view/ActionProvider.java +++ b/core/java/android/view/ActionProvider.java @@ -58,6 +58,7 @@ import android.content.Context; * @see MenuItem#getActionProvider() */ public abstract class ActionProvider { + private SubUiVisibilityListener mSubUiVisibilityListener; /** * Creates a new instance. @@ -138,4 +139,31 @@ public abstract class ActionProvider { */ public void onPrepareSubMenu(SubMenu subMenu) { } + + /** + * Notify the system that the visibility of an action view's sub-UI such as + * an anchored popup has changed. This will affect how other system + * visibility notifications occur. + * + * @hide Pending future API approval + */ + public void subUiVisibilityChanged(boolean isVisible) { + if (mSubUiVisibilityListener != null) { + mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible); + } + } + + /** + * @hide Internal use only + */ + public void setSubUiVisibilityListener(SubUiVisibilityListener listener) { + mSubUiVisibilityListener = listener; + } + + /** + * @hide Internal use only + */ + public interface SubUiVisibilityListener { + public void onSubUiVisibilityChanged(boolean isVisible); + } } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 335c66b036dc..55c821d50fbd 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -163,15 +163,13 @@ interface IWindowManager // These can only be called with the SET_ORIENTATION permission. /** - * Change the current screen rotation, constants as per - * {@link android.view.Surface}. - * @param rotation the intended rotation. + * Update the current screen rotation based on the current state of + * the world. * @param alwaysSendConfiguration Flag to force a new configuration to * be evaluated. This can be used when there are other parameters in * configuration that are changing. - * @param animFlags Animation flags as per {@link android.view.Surface}. */ - void setRotation(int rotation, boolean alwaysSendConfiguration, int animFlags); + void updateRotation(boolean alwaysSendConfiguration); /** * Retrieve the current screen orientation, constants as per diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 3880bc45b4f3..64d3d3101cdb 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -207,9 +207,6 @@ public class Surface implements Parcelable { /** Enable dithering when compositing this surface @hide */ public static final int SURFACE_DITHER = 0x04; - - /** Disable the orientation animation @hide */ - public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001; // The mSurfaceControl will only be present for Surfaces used by the window // server or system processes. When this class is parceled we defer to the @@ -393,7 +390,7 @@ public class Surface implements Parcelable { * set the orientation of the given display. * @param display * @param orientation - * @param flags + * @param flags Currently unused, set to 0. * @hide */ public static native void setOrientation(int display, int orientation, int flags); diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index c07faf63d222..1dbb083dd58f 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -375,12 +375,6 @@ public interface WindowManagerPolicy { /** Screen turned off because of proximity sensor */ public final int OFF_BECAUSE_OF_PROX_SENSOR = 4; - /** - * Magic constant to {@link IWindowManager#setRotation} to not actually - * modify the rotation. - */ - public final int USE_LAST_ROTATION = -1000; - /** When not otherwise specified by the activity's screenOrientation, rotation should be * determined by the system (that is, using sensors). */ public final int USER_ROTATION_FREE = 0; @@ -856,22 +850,30 @@ public interface WindowManagerPolicy { public boolean inKeyguardRestrictedKeyInputMode(); /** - * Given an orientation constant - * ({@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE - * ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE} or - * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_PORTRAIT - * ActivityInfo.SCREEN_ORIENTATION_PORTRAIT}), return a surface - * rotation. + * Given an orientation constant, returns the appropriate surface rotation, + * taking into account sensors, docking mode, rotation lock, and other factors. + * + * @param orientation An orientation constant, such as + * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}. + * @param lastRotation The most recently used rotation. + * @return The surface rotation to use. */ - public int rotationForOrientationLw(int orientation, int lastRotation, - boolean displayEnabled); - + public int rotationForOrientationLw(int orientation, int lastRotation); + /** - * 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. + * Given an orientation constant and a rotation, returns true if the rotation + * has compatible metrics to the requested orientation. For example, if + * the application requested landscape and got seascape, then the rotation + * has compatible metrics; if the application requested portrait and got landscape, + * then the rotation has incompatible metrics; if the application did not specify + * a preference, then anything goes. + * + * @param orientation An orientation constant, such as + * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}. + * @param rotation The rotation to check. + * @return True if the rotation is compatible with the requested orientation. */ - public int getLockedRotationLw(); + public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation); /** * Called when the system is mostly done booting to determine whether diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java index 76b47ca5a5e5..726bf4ad304e 100755 --- a/core/java/android/view/WindowOrientationListener.java +++ b/core/java/android/view/WindowOrientationListener.java @@ -118,14 +118,13 @@ public abstract class WindowOrientationListener { /** * Gets the current orientation. - * @param lastRotation - * @return + * @return The current rotation, or -1 if unknown. */ - public int getCurrentRotation(int lastRotation) { + public int getCurrentRotation() { if (mEnabled) { - return mSensorEventListener.getCurrentRotation(lastRotation); + return mSensorEventListener.getCurrentRotation(); } - return lastRotation; + return -1; } /** @@ -342,8 +341,8 @@ public abstract class WindowOrientationListener { mOrientationListener = orientationListener; } - public int getCurrentRotation(int lastRotation) { - return mRotation != ROTATION_UNKNOWN ? mRotation : lastRotation; + public int getCurrentRotation() { + return mRotation; // may be -1, if unknown } @Override diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java index 01587aac7d2a..b06c112cdf54 100644 --- a/core/java/android/view/textservice/TextServicesManager.java +++ b/core/java/android/view/textservice/TextServicesManager.java @@ -223,7 +223,7 @@ public final class TextServicesManager { try { sService.setSpellCheckerEnabled(enabled); } catch (RemoteException e) { - Log.e(TAG, "Error in setSpellCheckerSubtype:" + e); + Log.e(TAG, "Error in setSpellCheckerEnabled:" + e); } } @@ -234,7 +234,7 @@ public final class TextServicesManager { try { return sService.isSpellCheckerEnabled(); } catch (RemoteException e) { - Log.e(TAG, "Error in setSpellCheckerSubtype:" + e); + Log.e(TAG, "Error in isSpellCheckerEnabled:" + e); return false; } } diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index 25af3fa0e85a..5841283e4d75 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -16,6 +16,8 @@ package android.widget; +import com.android.internal.R; + import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -25,6 +27,7 @@ import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.view.ActionProvider; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -32,8 +35,6 @@ import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.ActivityChooserModel.ActivityChooserModelClient; -import com.android.internal.R; - /** * This class is a view for choosing an activity for handling a given {@link Intent}. * <p> @@ -105,6 +106,11 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod private final int mListPopupMaxWidth; /** + * The ActionProvider hosting this view, if applicable. + */ + ActionProvider mProvider; + + /** * Observer for the model data. */ private final DataSetObserver mModelDataSetOberver = new DataSetObserver() { @@ -129,6 +135,9 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod getListPopupWindow().dismiss(); } else { getListPopupWindow().show(); + if (mProvider != null) { + mProvider.subUiVisibilityChanged(true); + } } } } @@ -260,6 +269,14 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod } /** + * Set the provider hosting this view, if applicable. + * @hide Internal use only + */ + public void setProvider(ActionProvider provider) { + mProvider = provider; + } + + /** * Shows the popup window with activities. * * @return True if the popup was shown, false if already showing. @@ -307,6 +324,9 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth); popupWindow.setContentWidth(contentWidth); popupWindow.show(); + if (mProvider != null) { + mProvider.subUiVisibilityChanged(true); + } } } @@ -525,6 +545,9 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod // PopUpWindow.OnDismissListener#onDismiss public void onDismiss() { notifyOnDismissListener(); + if (mProvider != null) { + mProvider.subUiVisibilityChanged(false); + } } private void notifyOnDismissListener() { diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java index 17512d8c93d2..6a6d76766113 100644 --- a/core/java/android/widget/PopupMenu.java +++ b/core/java/android/widget/PopupMenu.java @@ -157,6 +157,8 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { * @hide */ public boolean onOpenSubMenu(MenuBuilder subMenu) { + if (subMenu == null) return false; + if (!subMenu.hasVisibleItems()) { return true; } diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java index 6e29024bcef4..36278907cea2 100644 --- a/core/java/android/widget/ShareActionProvider.java +++ b/core/java/android/widget/ShareActionProvider.java @@ -169,6 +169,7 @@ public class ShareActionProvider extends ActionProvider { mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true); Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId); activityChooserView.setExpandActivityOverflowButtonDrawable(drawable); + activityChooserView.setProvider(this); return activityChooserView; } diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java index fba6a5a3a049..0db1ccc000c9 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java @@ -24,6 +24,7 @@ import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; import android.util.SparseBooleanArray; +import android.view.ActionProvider; import android.view.MenuItem; import android.view.SoundEffectConstants; import android.view.View; @@ -40,7 +41,8 @@ import java.util.ArrayList; /** * MenuPresenter for building action menus as seen in the action bar and action modes. */ -public class ActionMenuPresenter extends BaseMenuPresenter { +public class ActionMenuPresenter extends BaseMenuPresenter + implements ActionProvider.SubUiVisibilityListener { private static final String TAG = "ActionMenuPresenter"; private View mOverflowButton; @@ -187,6 +189,17 @@ public class ActionMenuPresenter extends BaseMenuPresenter { public void updateMenuView(boolean cleared) { super.updateMenuView(cleared); + if (mMenu != null) { + final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems(); + final int count = actionItems.size(); + for (int i = 0; i < count; i++) { + final ActionProvider provider = actionItems.get(i).getActionProvider(); + if (provider != null) { + provider.setSubUiVisibilityListener(this); + } + } + } + final boolean hasOverflow = mReserveOverflow && mMenu != null && mMenu.getNonActionItems().size() > 0; if (hasOverflow) { @@ -483,6 +496,16 @@ public class ActionMenuPresenter extends BaseMenuPresenter { } } + @Override + public void onSubUiVisibilityChanged(boolean isVisible) { + if (isVisible) { + // Not a submenu, but treat it like one. + super.onSubMenuSelected(null); + } else { + mMenu.close(false); + } + } + private static class SavedState implements Parcelable { public int openSubMenuId; @@ -590,7 +613,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter { @Override public void onDismiss() { super.onDismiss(); - mSubMenu.close(); mActionButtonPopup = null; mOpenSubMenuId = 0; } @@ -600,12 +622,17 @@ public class ActionMenuPresenter extends BaseMenuPresenter { @Override public boolean onOpenSubMenu(MenuBuilder subMenu) { + if (subMenu == null) return false; + mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); return false; } @Override public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + if (menu instanceof SubMenuBuilder) { + ((SubMenuBuilder) menu).getRootMenu().close(false); + } } } diff --git a/core/java/com/android/internal/view/menu/IconMenuPresenter.java b/core/java/com/android/internal/view/menu/IconMenuPresenter.java index d1b1dae80315..24ddad668ac3 100644 --- a/core/java/com/android/internal/view/menu/IconMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/IconMenuPresenter.java @@ -187,7 +187,9 @@ public class IconMenuPresenter extends BaseMenuPresenter { @Override public boolean onOpenSubMenu(MenuBuilder subMenu) { - mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); + if (subMenu != null) { + mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); + } return false; } diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml index 694db50a84ee..3343d8b51291 100644 --- a/core/res/res/layout/keyguard_screen_password_landscape.xml +++ b/core/res/res/layout/keyguard_screen_password_landscape.xml @@ -170,6 +170,7 @@ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" android:layout_width="270dip" android:layout_height="wrap_content" + android:layout_marginLeft="4dip" android:layout_marginRight="4dip" android:background="#40000000" android:layout_marginTop="5dip" diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml index 27a51dad639c..2a66d7dba841 100644 --- a/core/res/res/layout/keyguard_screen_password_portrait.xml +++ b/core/res/res/layout/keyguard_screen_password_portrait.xml @@ -132,7 +132,7 @@ <!-- Numeric keyboard --> <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_marginLeft="4dip" android:layout_marginRight="4dip" android:paddingTop="4dip" android:paddingBottom="4dip" diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml index 13bbac60f5c8..7fa76589957d 100644 --- a/core/res/res/values-sw600dp/config.xml +++ b/core/res/res/values-sw600dp/config.xml @@ -32,5 +32,8 @@ <!-- see comment in values/config.xml --> <dimen name="config_prefDialogWidth">580dp</dimen> + <!-- If true, the screen can be rotated via the accelerometer in all 4 + rotations as the default behavior. --> + <bool name="config_allowAllRotations">true</bool> </resources> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 847afa051440..11531fc65d5f 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1561,8 +1561,21 @@ <enum name="xhdpi" value="320" /> </attr> </declare-styleable> - - + + <!-- The attribute that holds a Base64-encoded public key. --> + <attr name="publicKey" format="string" /> + + <!-- Attributes relating to a package verifier --> + <declare-styleable name="AndroidManifestPackageVerifier" parent="AndroidManifest"> + <!-- Specifies the Java-style package name that defines this + package verifier. --> + <attr name="name" /> + + <!-- The Base64 encoded public key of the package verifier's + signature. --> + <attr name="publicKey" /> + </declare-styleable> + <!-- Declaration of an {@link android.content.Intent} object in XML. May also include zero or more {@link #IntentCategory <category> and {@link #Extra <extra>} tags. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 1e5358e20dcb..5eb3e5a11ed2 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -231,7 +231,7 @@ <!-- If true, the screen can be rotated via the accelerometer in all 4 rotations as the default behavior. --> - <bool name="config_allowAllRotations">true</bool> + <bool name="config_allowAllRotations">false</bool> <!-- If true, the direction rotation is applied to get to an application's requested orientation is reversed. Normally, the model is that landscape is @@ -400,9 +400,9 @@ <!-- Diable lockscreen rotation by default --> <bool name="config_enableLockScreenRotation">false</bool> - <!-- Diable puk unlockscreen by default. + <!-- Enable puk unlockscreen by default. If unlock screen is disabled, the puk should be unlocked through Emergency Dialer --> - <bool name="config_enable_puk_unlock_screen">false</bool> + <bool name="config_enable_puk_unlock_screen">true</bool> <!-- Control the behavior when the user long presses the home button. 0 - Nothing diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 848fb8bdb745..97d5afe8cfdf 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1768,6 +1768,7 @@ <public type="attr" name="listPreferredItemPaddingLeft" id="0x010103a3" /> <public type="attr" name="listPreferredItemPaddingRight" id="0x010103a4" /> <public type="attr" name="requiresFadingEdge" id="0x010103a5" /> + <public type="attr" name="publicKey" id="0x010103a6" /> <public type="style" name="TextAppearance.SuggestionHighlight" id="0x01030118" /> <public type="style" name="Theme.Holo.Light.DarkActionBar" id="0x01030119" /> diff --git a/data/fonts/AndroidClock.ttf b/data/fonts/AndroidClock.ttf Binary files differindex 7ebc9634b878..3fa6d8867770 100644 --- a/data/fonts/AndroidClock.ttf +++ b/data/fonts/AndroidClock.ttf diff --git a/data/fonts/AndroidClock_Highlight.ttf b/data/fonts/AndroidClock_Highlight.ttf Binary files differindex 7ebc9634b878..3fa6d8867770 100644 --- a/data/fonts/AndroidClock_Highlight.ttf +++ b/data/fonts/AndroidClock_Highlight.ttf diff --git a/data/fonts/AndroidClock_Solid.ttf b/data/fonts/AndroidClock_Solid.ttf Binary files differindex 7ebc9634b878..3fa6d8867770 100644 --- a/data/fonts/AndroidClock_Solid.ttf +++ b/data/fonts/AndroidClock_Solid.ttf diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 9c3a0bea18e8..371658399495 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -222,8 +222,7 @@ <li><a href="<?cs var:toroot ?>guide/topics/manifest/receiver-element.html"><receiver></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/service-element.html"><service></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-gl-texture-element.html"><supports-gl-texture></a></li> - <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-screens-element.html"><supports-screens></a> - <span class="new">updated</span></li> <!-- ##api level 4## --> + <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-screens-element.html"><supports-screens></a></li><!-- ##api level 4## --> <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-configuration-element.html"><uses-configuration></a></li> <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-feature-element.html"><uses-feature></a></li> <!-- ##api level 4## --> <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-library-element.html"><uses-library></a></li> @@ -244,7 +243,7 @@ </a></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html"> <span class="en">3D with OpenGL</span> - </a><span class="new">updated</span></li> + </a></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html"> <span class="en">Property Animation</span> </a></li> @@ -271,7 +270,7 @@ <li><a href="<?cs var:toroot ?>guide/topics/media/index.html"> <span class="en">Media</span> - </a><span class="new">updated</span></li> + </a></li> <li> <a href="<?cs var:toroot ?>guide/topics/clipboard/copy-paste.html"> <span class="en">Copy and Paste</span> @@ -408,7 +407,6 @@ </li> <li><a href="<?cs var:toroot ?>guide/market/publishing/multiple-apks.html"> <span class="en">Multiple APK Support</span></a> - <span class="new">new!</span> </li> </ul> </li> @@ -569,7 +567,7 @@ </a></div> <ul> <li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li> - <li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT</a> <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT</a></li> <li><a href="<?cs var:toroot ?>guide/developing/tools/android.html">android</a></li> <li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a> <li><a href="<?cs var:toroot ?>guide/developing/tools/dmtracedump.html">dmtracedump</a></li> @@ -672,14 +670,14 @@ <li class="toggle-list"> <div><a href="<?cs var:toroot ?>guide/practices/screens_support.html"> <span class="en">Supporting Multiple Screens</span> - </a> <span class="new">updated</span></div> + </a></div> <ul> <li><a href="<?cs var:toroot ?>guide/practices/screens-distribution.html"> <span class="en">Distributing to Specific Screens</span> </a></li> <li><a href="<?cs var:toroot ?>guide/practices/screen-compat-mode.html"> <span class="en">Screen Compatibility Mode</span> - </a> <span class="new">new!</span></li> + </a></li> <li><a href="<?cs var:toroot ?>guide/practices/screens-support-1.5.html"> <span class="en">Strategies for Android 1.5</span> </a></li> @@ -737,11 +735,11 @@ <li class="toggle-list"> <div><a href="<?cs var:toroot ?>guide/practices/design/performance.html"> <span class="en">Designing for Performance</span> - </a> <span class="new-child">new!</span></div> + </a></div> <ul> <li><a href="<?cs var:toroot ?>guide/practices/design/jni.html"> <span class="en">JNI Tips</span> - </a> <span class="new">new!</span></li> + </a></li> </ul> </li> <li><a href="<?cs var:toroot ?>guide/practices/design/responsiveness.html"> diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js index 720e14314c2a..f799b0cea5e0 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -31,7 +31,8 @@ var ANDROID_TAGS = { }, misc: { 'external': 'External', - 'new': 'New' + 'new': 'New', + 'updated': 'Updated' } }; @@ -377,7 +378,7 @@ var ANDROID_RESOURCES = [ /////////////////// { - tags: ['sample', 'new'], + tags: ['sample'], path: 'samples/AccelerometerPlay/index.html', title: { en: 'Accelerometer Play' @@ -387,7 +388,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new', 'accessibility'], + tags: ['sample', 'accessibility'], path: 'samples/AccessibilityService/index.html', title: { en: 'Accessibility Service' @@ -407,7 +408,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'layout', 'ui', 'fragment', 'loader', 'new'], + tags: ['sample', 'layout', 'ui', 'fragment', 'loader'], path: 'samples/Support4Demos/index.html', title: { en: 'API 4+ Support Demos' @@ -417,7 +418,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'layout', 'ui', 'new'], + tags: ['sample', 'layout', 'ui'], path: 'samples/Support13Demos/index.html', title: { en: 'API 13+ Support Demos' @@ -487,13 +488,13 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new', 'newfeature', 'ui'], + tags: ['sample', 'updated', 'newfeature', 'ui'], path: 'samples/HoneycombGallery/index.html', title: { en: 'Honeycomb Gallery' }, description: { - en: 'An image gallery application using APIs that are new in Android 3.0 (a.k.a. Honeycomb).' + en: 'An image gallery application that demonstrates a variety of new APIs in Android 3.0 (Honeycomb). In addition to providing a tablet-optimized design, it also supports handsets running Android 4.0 (Ice Cream Sandwich) and beyond, so is a good example of how to reuse Fragments to support different screen sizes.' } }, { @@ -547,7 +548,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new', 'media' ], + tags: ['sample', 'media' ], path: 'samples/RandomMusicPlayer/index.html', title: { en: 'Random Music Player' @@ -557,7 +558,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new', 'newfeature', 'performance', 'gamedev', 'gl'], + tags: ['sample', 'newfeature', 'performance', 'gamedev', 'gl'], path: 'samples/RenderScript/index.html', title: { en: 'RenderScript' @@ -637,7 +638,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new', 'newfeature', 'widgets'], + tags: ['sample', 'newfeature', 'widgets'], path: 'samples/StackWidget/index.html', title: { en: 'StackView Widget' @@ -667,7 +668,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'new', 'newfeature'], + tags: ['sample', 'newfeature'], path: 'samples/USB/index.html', title: { en: 'USB' @@ -683,7 +684,7 @@ var ANDROID_RESOURCES = [ en: 'Voicemail Provider Demo' }, description: { - en: 'A sample application to demonstrate how to use voicemail content provider APIs.' + en: 'A sample application to demonstrate how to use voicemail content provider APIs in Android 4.0.' } }, { @@ -707,7 +708,7 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'widgets', 'newfeature', 'new'], + tags: ['sample', 'widgets', 'newfeature'], path: 'samples/WeatherListWidget/index.html', title: { en: 'Weather List Widget' @@ -733,7 +734,7 @@ var ANDROID_RESOURCES = [ en: 'Text To Speech Engine' }, description: { - en: 'An example Text To Speech engine written using the android text to speech engine API.' + en: 'An example Text To Speech engine written using the Android text to speech engine API in Android 4.0.' } }, diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs index a00ca125a6cf..92b912d3fdc7 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -77,7 +77,7 @@ class="new">new!</span></li> <ul> <li class="toggle-list"> <div><a href="<?cs var:toroot ?>sdk/android-3.2.html"> - <span class="en">Android 3.2 Platform</span></a> <span class="new">new!</span></div> + <span class="en">Android 3.2 Platform</span></a></div> <ul> <!-- <li><a href="<?cs var:toroot ?>sdk/android-3.2-highlights.html">Platform Highlights</a></li> --> <li><a href="<?cs var:toroot ?>sdk/api_diff/13/changes.html">API Differences Report »</a></li> @@ -142,11 +142,10 @@ class="new">new!</span></li> </li> </ul> <ul> - <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r12</a> <span -class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r12</a></li> <li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li> <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Compatibility Package, -r3</a> <span class="new">new!</span></li> +r3</a></li> </ul> </li> <li> @@ -169,7 +168,7 @@ r3</a> <span class="new">new!</span></li> <span style="display:none" class="ja"></span> <span style="display:none" class="zh-CN"></span> <span style="display:none" class="zh-TW"></span></a> - <span class="new">new!</span></li> + </li> </ul> </li> <li> @@ -183,8 +182,7 @@ r3</a> <span class="new">new!</span></li> <span style="display:none" class="zh-TW"></span> </h2> <ul> - <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6b</a> - <span class="new">new!</span> + <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6b</a> </li> <li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li> </ul> diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp index 3e4fe8c07d23..b2fa05378258 100644 --- a/drm/drmserver/DrmManager.cpp +++ b/drm/drmserver/DrmManager.cpp @@ -98,21 +98,27 @@ void DrmManager::removeUniqueId(int uniqueId) { } status_t DrmManager::loadPlugIns() { + + String8 vendorPluginDirPath("/vendor/lib/drm"); + loadPlugIns(vendorPluginDirPath); + String8 pluginDirPath("/system/lib/drm"); - return loadPlugIns(pluginDirPath); + loadPlugIns(pluginDirPath); + return DRM_NO_ERROR; + } status_t DrmManager::loadPlugIns(const String8& plugInDirPath) { - if (mSupportInfoToPlugInIdMap.isEmpty()) { - mPlugInManager.loadPlugIns(plugInDirPath); - Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); - for (unsigned int i = 0; i < plugInPathList.size(); ++i) { - String8 plugInPath = plugInPathList[i]; - DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0); - if (NULL != info) { + mPlugInManager.loadPlugIns(plugInDirPath); + Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList(); + for (unsigned int i = 0; i < plugInPathList.size(); ++i) { + String8 plugInPath = plugInPathList[i]; + DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0); + if (NULL != info) { + if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) { mSupportInfoToPlugInIdMap.add(*info, plugInPath); - delete info; } + delete info; } } return DRM_NO_ERROR; diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index 6b31ca4cb8bb..e0f4cf900adf 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -88,11 +88,6 @@ public: eElectronBeamAnimationOff = 0x10 }; - // flags for setOrientation - enum { - eOrientationAnimationDisable = 0x00000001 - }; - /* create connection with surface flinger, requires * ACCESS_SURFACE_FLINGER permission */ @@ -112,7 +107,8 @@ public: virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0; virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0; - /* Set display orientation. requires ACCESS_SURFACE_FLINGER permission */ + /* Set display orientation. requires ACCESS_SURFACE_FLINGER permission + * No flags are currently defined. Set flags to 0. */ virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags) = 0; /* signal that we're done booting. diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 4f39e6980f5b..b851ab7ec81c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -16,6 +16,21 @@ package com.android.providers.settings; +import android.app.backup.BackupAgentHelper; +import android.app.backup.BackupDataInput; +import android.app.backup.BackupDataOutput; +import android.app.backup.FullBackupDataOutput; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.os.FileUtils; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.provider.Settings; +import android.util.Log; + import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -27,28 +42,13 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; -import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.zip.CRC32; -import android.app.backup.BackupDataInput; -import android.app.backup.BackupDataOutput; -import android.app.backup.BackupAgentHelper; -import android.app.backup.FullBackupDataOutput; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.net.wifi.WifiManager; -import android.os.FileUtils; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.Log; - /** * Performs backup and restore of the System and Secure settings. * List of settings that are backed up are stored in the Settings.java file @@ -79,8 +79,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { // Versioning of the 'full backup' format private static final int FULL_BACKUP_VERSION = 1; - private static String[] sortedSystemKeys = null; - private static String[] sortedSecureKeys = null; + private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE; private static final byte[] EMPTY_DATA = new byte[0]; @@ -112,6 +111,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { private WifiManager mWfm; private static String mWifiConfigFile; + @Override public void onCreate() { if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked"); @@ -348,26 +348,17 @@ public class SettingsBackupAgent extends BackupAgentHelper { } private byte[] getSystemSettings() { - Cursor sortedCursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, - null, null, Settings.NameValueTable.NAME); - // Copy and sort the array - if (sortedSystemKeys == null) { - sortedSystemKeys = copyAndSort(Settings.System.SETTINGS_TO_BACKUP); - } - byte[] result = extractRelevantValues(sortedCursor, sortedSystemKeys); - sortedCursor.close(); + Cursor cursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, null, + null, null); + byte[] result = extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP); + cursor.close(); return result; } private byte[] getSecureSettings() { - Cursor sortedCursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, - null, null, Settings.NameValueTable.NAME); - // Copy and sort the array - if (sortedSecureKeys == null) { - sortedSecureKeys = copyAndSort(Settings.Secure.SETTINGS_TO_BACKUP); - } - byte[] result = extractRelevantValues(sortedCursor, sortedSecureKeys); - sortedCursor.close(); + Cursor cursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, null, + null, null); + byte[] result = extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP); return result; } @@ -383,119 +374,132 @@ public class SettingsBackupAgent extends BackupAgentHelper { } private void restoreSettings(byte[] settings, int bytes, Uri contentUri) { - if (DEBUG) Log.i(TAG, "restoreSettings: " + contentUri); + if (DEBUG) { + Log.i(TAG, "restoreSettings: " + contentUri); + } + + // Figure out the white list. String[] whitelist = null; if (contentUri.equals(Settings.Secure.CONTENT_URI)) { whitelist = Settings.Secure.SETTINGS_TO_BACKUP; } else if (contentUri.equals(Settings.System.CONTENT_URI)) { whitelist = Settings.System.SETTINGS_TO_BACKUP; + } else { + throw new IllegalArgumentException("Unknown URI: " + contentUri); } - ContentValues cv = new ContentValues(2); + // Restore only the white list data. int pos = 0; - while (pos < bytes) { - int length = readInt(settings, pos); - pos += 4; - String settingName = length > 0? new String(settings, pos, length) : null; - pos += length; - length = readInt(settings, pos); - pos += 4; - String settingValue = length > 0? new String(settings, pos, length) : null; - pos += length; - if (!TextUtils.isEmpty(settingName) && !TextUtils.isEmpty(settingValue)) { - //Log.i(TAG, "Restore " + settingName + " = " + settingValue); - - // Only restore settings in our list of known-acceptable data - if (invalidSavedSetting(whitelist, settingName)) { - continue; + Map<String, String> cachedEntries = new HashMap<String, String>(); + ContentValues contentValues = new ContentValues(2); + SettingsHelper settingsHelper = mSettingsHelper; + + final int whiteListSize = whitelist.length; + for (int i = 0; i < whiteListSize; i++) { + String key = whitelist[i]; + String value = cachedEntries.remove(key); + + // If the value not cached, let us look it up. + if (value == null) { + while (pos < bytes) { + int length = readInt(settings, pos); + pos += INTEGER_BYTE_COUNT; + String dataKey = length > 0 ? new String(settings, pos, length) : null; + pos += length; + length = readInt(settings, pos); + pos += INTEGER_BYTE_COUNT; + String dataValue = length > 0 ? new String(settings, pos, length) : null; + pos += length; + if (key.equals(dataKey)) { + value = dataValue; + break; + } + cachedEntries.put(dataKey, dataValue); } + } - if (mSettingsHelper.restoreValue(settingName, settingValue)) { - cv.clear(); - cv.put(Settings.NameValueTable.NAME, settingName); - cv.put(Settings.NameValueTable.VALUE, settingValue); - getContentResolver().insert(contentUri, cv); - } + if (value == null) { + continue; } - } - } - // Returns 'true' if the given setting is one that we refuse to restore - private boolean invalidSavedSetting(String[] knownNames, String candidate) { - // no filter? allow everything - if (knownNames == null) { - return false; - } + if (settingsHelper.restoreValue(key, value)) { + contentValues.clear(); + contentValues.put(Settings.NameValueTable.NAME, key); + contentValues.put(Settings.NameValueTable.VALUE, value); + getContentResolver().insert(contentUri, contentValues); + } - // whitelisted setting? allow it - for (String name : knownNames) { - if (name.equals(candidate)) { - return false; + if (DEBUG) { + Log.d(TAG, "Restored setting: " + key + "=" + value); } } - - // refuse everything else - if (DEBUG) Log.v(TAG, "Ignoring restore datum: " + candidate); - return true; - } - - private String[] copyAndSort(String[] keys) { - String[] sortedKeys = new String[keys.length]; - System.arraycopy(keys, 0, sortedKeys, 0, keys.length); - Arrays.sort(sortedKeys); - return sortedKeys; } /** - * Given a cursor sorted by key name and a set of keys sorted by name, - * extract the required keys and values and write them to a byte array. - * @param sortedCursor - * @param sortedKeys - * @return + * Given a cursor and a set of keys, extract the required keys and + * values and write them to a byte array. + * + * @param cursor A cursor with settings data. + * @param settings The settings to extract. + * @return The byte array of extracted values. */ - byte[] extractRelevantValues(Cursor sortedCursor, String[] sortedKeys) { - byte[][] values = new byte[sortedKeys.length * 2][]; // keys and values - if (!sortedCursor.moveToFirst()) { + private byte[] extractRelevantValues(Cursor cursor, String[] settings) { + final int settingsCount = settings.length; + byte[][] values = new byte[settingsCount * 2][]; // keys and values + if (!cursor.moveToFirst()) { Log.e(TAG, "Couldn't read from the cursor"); return new byte[0]; } - int keyIndex = 0; + + // Obtain the relevant data in a temporary array. int totalSize = 0; - while (!sortedCursor.isAfterLast()) { - String name = sortedCursor.getString(COLUMN_NAME); - while (sortedKeys[keyIndex].compareTo(name.toString()) < 0) { - keyIndex++; - if (keyIndex == sortedKeys.length) break; - } - if (keyIndex < sortedKeys.length && name.equals(sortedKeys[keyIndex])) { - String value = sortedCursor.getString(COLUMN_VALUE); - byte[] nameBytes = name.toString().getBytes(); - totalSize += 4 + nameBytes.length; - values[keyIndex * 2] = nameBytes; - byte[] valueBytes; - if (TextUtils.isEmpty(value)) { - valueBytes = null; - totalSize += 4; - } else { - valueBytes = value.toString().getBytes(); - totalSize += 4 + valueBytes.length; - //Log.i(TAG, "Backing up " + name + " = " + value); + int backedUpSettingIndex = 0; + Map<String, String> cachedEntries = new HashMap<String, String>(); + for (int i = 0; i < settingsCount; i++) { + String key = settings[i]; + String value = cachedEntries.remove(key); + + // If the value not cached, let us look it up. + if (value == null) { + while (!cursor.isAfterLast()) { + String cursorKey = cursor.getString(COLUMN_NAME); + String cursorValue = cursor.getString(COLUMN_VALUE); + cursor.moveToNext(); + if (key.equals(cursorKey)) { + value = cursorValue; + break; + } + cachedEntries.put(cursorKey, cursorValue); } - values[keyIndex * 2 + 1] = valueBytes; - keyIndex++; } - if (keyIndex == sortedKeys.length || !sortedCursor.moveToNext()) { - break; + + if (value == null) { + continue; + } + + // Write the key and value in the intermediary array. + byte[] keyBytes = key.getBytes(); + totalSize += INTEGER_BYTE_COUNT + keyBytes.length; + values[backedUpSettingIndex * 2] = keyBytes; + + byte[] valueBytes = value.getBytes(); + totalSize += INTEGER_BYTE_COUNT + valueBytes.length; + values[backedUpSettingIndex * 2 + 1] = valueBytes; + + backedUpSettingIndex++; + + if (DEBUG) { + Log.d(TAG, "Backed up setting: " + key + "=" + value); } } + // Aggregate the result. byte[] result = new byte[totalSize]; int pos = 0; - for (int i = 0; i < sortedKeys.length * 2; i++) { - if (values[i] != null) { - pos = writeInt(result, pos, values[i].length); - pos = writeBytes(result, pos, values[i]); - } + final int keyValuePairCount = backedUpSettingIndex * 2; + for (int i = 0; i < keyValuePairCount; i++) { + pos = writeInt(result, pos, values[i].length); + pos = writeBytes(result, pos, values[i]); } return result; } @@ -647,14 +651,14 @@ public class SettingsBackupAgent extends BackupAgentHelper { * @param out byte array * @param pos current pos in array * @param value integer to write - * @return the index after adding the size of an int (4) + * @return the index after adding the size of an int (4) in bytes. */ private int writeInt(byte[] out, int pos, int value) { out[pos + 0] = (byte) ((value >> 24) & 0xFF); out[pos + 1] = (byte) ((value >> 16) & 0xFF); out[pos + 2] = (byte) ((value >> 8) & 0xFF); out[pos + 3] = (byte) ((value >> 0) & 0xFF); - return pos + 4; + return pos + INTEGER_BYTE_COUNT; } private int writeBytes(byte[] out, int pos, byte[] value) { diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java index 958f555ff567..2a2370950304 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java @@ -484,6 +484,9 @@ public class KeyguardUpdateMonitor { public void registerInfoCallback(InfoCallback callback) { if (!mInfoCallbacks.contains(callback)) { mInfoCallbacks.add(callback); + // notify the register the current state right away + // TODO: need call other callback methods + callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn); } else { if (DEBUG) Log.e(TAG, "Object tried to add another INFO callback", new Exception("Whoops")); @@ -497,6 +500,10 @@ public class KeyguardUpdateMonitor { public void registerSimStateCallback(SimStateCallback callback) { if (!mSimStateCallbacks.contains(callback)) { mSimStateCallbacks.add(callback); + // notify the register the current sim state right away, + // otherwise the register won't receive any state until + // sim state gets changed again. + callback.onSimStateChanged(mSimState); } else { if (DEBUG) Log.e(TAG, "Object tried to add another SIM callback", new Exception("Whoops")); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 9a3031dc1d89..bca95d3438e9 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -3471,6 +3471,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } public boolean onOpenSubMenu(MenuBuilder subMenu) { + if (subMenu == null) return false; + // Set a simple callback for the submenu subMenu.setCallback(this); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index c8c0041b2f95..a977618c8972 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -280,7 +280,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE; int mUserRotation = Surface.ROTATION_0; - boolean mAllowAllRotations; + int mAllowAllRotations = -1; boolean mCarDockEnablesAccelerometer; boolean mDeskDockEnablesAccelerometer; int mLidKeyboardAccessibility; @@ -385,9 +385,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mPortraitRotation = 0; // default portrait rotation int mUpsideDownRotation = 0; // "other" portrait rotation - // Nothing to see here, move along... - int mFancyRotationAnimation; - // What we do when the user long presses on home private int mLongPressOnHomeBehavior = -1; @@ -439,12 +436,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public void onChange(boolean selfChange) { updateSettings(); - try { - mWindowManager.setRotation(USE_LAST_ROTATION, false, - mFancyRotationAnimation); - } catch (RemoteException e) { - // Ignore - } + updateRotation(false); } } @@ -457,45 +449,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void onOrientationChanged(int rotation) { // Send updates based on orientation value if (localLOGV) Log.v(TAG, "onOrientationChanged, rotation changed to " +rotation); - try { - mWindowManager.setRotation(rotation, false, - mFancyRotationAnimation); - } catch (RemoteException e) { - // Ignore - - } - } + updateRotation(false); + } } MyOrientationListener mOrientationListener; - boolean useSensorForOrientationLp(int appOrientation) { - // The app says use the sensor. - if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { - return true; - } - // The user preference says we can rotate, and the app is willing to rotate. - if (mAccelerometerDefault != 0 && - (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) { - return true; - } - // We're in a dock that has a rotation affinity, and the app is willing to rotate. - if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) - || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) { - // Note we override the nosensor flag here. - if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { - return true; - } - } - // Else, don't use the sensor. - return false; - } - /* * We always let the sensor be switched on by default except when * the user has explicitly disabled sensor based rotation or when the @@ -723,8 +681,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.integer.config_carDockRotation); mDeskDockRotation = readRotation( com.android.internal.R.integer.config_deskDockRotation); - mAllowAllRotations = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_allowAllRotations); mCarDockEnablesAccelerometer = mContext.getResources().getBoolean( com.android.internal.R.bool.config_carDockEnablesAccelerometer); mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean( @@ -826,8 +782,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { mIncallPowerBehavior = Settings.Secure.getInt(resolver, Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); - mFancyRotationAnimation = Settings.System.getInt(resolver, - "fancy_rotation_anim", 0) != 0 ? 0x80 : 0; int accelerometerDefault = Settings.System.getInt(resolver, Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION); @@ -882,7 +836,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { updateScreenSaverTimeoutLocked(); } if (updateRotation) { - updateRotation(0); + updateRotation(true); } if (addView != null) { WindowManager.LayoutParams lp = new WindowManager.LayoutParams( @@ -1025,8 +979,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public void adjustConfigurationLw(Configuration config) { readLidState(); - - mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN); + updateKeyboardVisibility(); if (config.keyboard == Configuration.KEYBOARD_NOKEYS) { config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES; @@ -2295,8 +2248,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { // lid changed state mLidOpen = lidOpen ? LID_OPEN : LID_CLOSED; + updateKeyboardVisibility(); + boolean awakeNow = mKeyguardMediator.doLidChangeTq(lidOpen); - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); + updateRotation(true); if (awakeNow) { // If the lid is opening and we don't have to keep the // keyguard up, then we can turn on the screen @@ -2325,7 +2280,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { void setHdmiPlugged(boolean plugged) { if (mHdmiPlugged != plugged) { mHdmiPlugged = plugged; - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); + updateRotation(true); Intent intent = new Intent(ACTION_HDMI_PLUGGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged); @@ -2802,7 +2757,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } catch (RemoteException e) { } } - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); + updateRotation(true); updateOrientationListenerLp(); } }; @@ -2914,10 +2869,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } - - public int rotationForOrientationLw(int orientation, int lastRotation, - boolean displayEnabled) { + @Override + public int rotationForOrientationLw(int orientation, int lastRotation) { if (false) { Slog.v(TAG, "rotationForOrientationLw(orient=" + orientation + ", last=" + lastRotation @@ -2928,128 +2882,136 @@ public class PhoneWindowManager implements WindowManagerPolicy { } synchronized (mLock) { + int sensorRotation = mOrientationListener.getCurrentRotation(); // may be -1 + + int preferredRotation = -1; + if (mHdmiPlugged) { + // Ignore sensor when plugged into HDMI. + preferredRotation = mLandscapeRotation; + } else if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) { + // Ignore sensor when lid switch is open and rotation is forced. + preferredRotation = mLidOpenRotation; + } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR + && ((mCarDockEnablesAccelerometer && sensorRotation >= 0) + || mCarDockRotation >= 0)) { + // Ignore sensor when in car dock unless explicitly enabled. + // This case can override the behavior of NOSENSOR, and can also + // enable 180 degree rotation while docked. + preferredRotation = mCarDockEnablesAccelerometer && sensorRotation >= 0 + ? sensorRotation : mCarDockRotation; + } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK + && ((mDeskDockEnablesAccelerometer && sensorRotation >= 0) + || mDeskDockRotation >= 0)) { + // Ignore sensor when in desk dock unless explicitly enabled. + // This case can override the behavior of NOSENSOR, and can also + // enable 180 degree rotation while docked. + preferredRotation = mDeskDockEnablesAccelerometer && sensorRotation >= 0 + ? sensorRotation : mDeskDockRotation; + } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { + // Ignore sensor when user locked rotation. + preferredRotation = mUserRotation; + } else if ((mAccelerometerDefault != 0 + && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER + || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) + || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR + || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR + || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE + || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) { + // Otherwise, use sensor only if requested by the application or enabled + // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR. + if (mAllowAllRotations < 0) { + // Can't read this during init() because the context doesn't + // have display metrics at that time so we cannot determine + // tablet vs. phone then. + mAllowAllRotations = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0; + } + if (sensorRotation != Surface.ROTATION_180 + || mAllowAllRotations == 1 + || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) { + preferredRotation = sensorRotation; + } else { + preferredRotation = lastRotation; + } + } + + // TODO: Sometimes, we might want to override the application-requested + // orientation, such as when HDMI is plugged in or when docked. + // We can do that by modifying the appropriate cases above to return + // the preferred orientation directly instead of continuing on down here. + switch (orientation) { case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: - //always return portrait if orientation set to portrait + // Always return portrait if orientation set to portrait. return mPortraitRotation; + case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: - //always return landscape if orientation set to landscape + // Always return landscape if orientation set to landscape. return mLandscapeRotation; + case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: - //always return portrait if orientation set to portrait + // Always return portrait if orientation set to portrait. return mUpsideDownRotation; + case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: - //always return seascape if orientation set to reverse landscape + // Always return seascape if orientation set to reverse landscape. return mSeascapeRotation; + case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: - //return either landscape rotation based on the sensor - return getCurrentLandscapeRotation(lastRotation); - case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: - return getCurrentPortraitRotation(lastRotation); - } + // Return either landscape rotation. + if (isLandscapeOrSeascape(preferredRotation)) { + return preferredRotation; + } + if (isLandscapeOrSeascape(lastRotation)) { + return lastRotation; + } + return mLandscapeRotation; - // case for nosensor meaning ignore sensor and consider only lid - // or orientation sensor disabled - //or case.unspecified - if (mHdmiPlugged) { - return mLandscapeRotation; - } else if (mLidOpen == LID_OPEN) { - return mLidOpenRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) { - return mCarDockRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { - return mDeskDockRotation; - } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { - return mUserRotation; - } else { - if (useSensorForOrientationLp(orientation)) { - // Disable 180 degree rotation unless allowed by default for the device - // or explicitly requested by the application. - int rotation = mOrientationListener.getCurrentRotation(lastRotation); - if (rotation == Surface.ROTATION_180 - && !mAllowAllRotations - && orientation != ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) { + case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: + // Return either portrait rotation. + if (isAnyPortrait(preferredRotation)) { + return preferredRotation; + } + if (isAnyPortrait(lastRotation)) { return lastRotation; } - return rotation; - } - return Surface.ROTATION_0; - } - } - } + return mPortraitRotation; - public int getLockedRotationLw() { - synchronized (mLock) { - if (false) { - // Not yet working. - if (mHdmiPlugged) { + default: + // For USER, UNSPECIFIED and NOSENSOR, just return the preferred + // orientation we already calculated. + if (preferredRotation >= 0) { + return preferredRotation; + } return Surface.ROTATION_0; - } else if (mLidOpen == LID_OPEN) { - return mLidOpenRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) { - return mCarDockRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { - return mDeskDockRotation; - } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { - return mUserRotation; - } } - return -1; } } - private int getCurrentLandscapeRotation(int lastRotation) { - // if the user has locked rotation, we ignore the sensor - if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { - if (isLandscapeOrSeascape(mUserRotation)) { - return mUserRotation; - } else { - // it seems odd to obey the sensor at all if rotation lock is enabled - return mLandscapeRotation; - } - } + @Override + public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) { + switch (orientation) { + case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: + case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: + case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: + return isAnyPortrait(rotation); + + case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: + case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: + case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: + return isLandscapeOrSeascape(rotation); - int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); - if (isLandscapeOrSeascape(sensorRotation)) { - return sensorRotation; - } - // try to preserve the old rotation if it was landscape - if (isLandscapeOrSeascape(lastRotation)) { - return lastRotation; + default: + return true; } - // default to one of the primary landscape rotation - return mLandscapeRotation; - } - - private boolean isLandscapeOrSeascape(int sensorRotation) { - return sensorRotation == mLandscapeRotation || sensorRotation == mSeascapeRotation; } - private int getCurrentPortraitRotation(int lastRotation) { - // if the user has locked rotation, we ignore the sensor - if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { - if (isAnyPortrait(mUserRotation)) { - return mUserRotation; - } else { - // it seems odd to obey the sensor at all if rotation lock is enabled - return mPortraitRotation; - } - } - - int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation); - if (isAnyPortrait(sensorRotation)) { - return sensorRotation; - } - // try to preserve the old rotation if it was portrait - if (isAnyPortrait(lastRotation)) { - return lastRotation; - } - // default to one of the primary portrait rotations - return mPortraitRotation; + private boolean isLandscapeOrSeascape(int rotation) { + return rotation == mLandscapeRotation || rotation == mSeascapeRotation; } - private boolean isAnyPortrait(int sensorRotation) { - return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation; + private boolean isAnyPortrait(int rotation) { + return rotation == mPortraitRotation || rotation == mUpsideDownRotation; } @@ -3298,26 +3260,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public void enableScreenAfterBoot() { readLidState(); - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); + updateKeyboardVisibility(); + + updateRotation(true); } - void updateRotation(int animFlags) { + private void updateKeyboardVisibility() { mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN); - int rotation = Surface.ROTATION_0; - if (mHdmiPlugged) { - rotation = Surface.ROTATION_0; - } else if (mLidOpen == LID_OPEN) { - rotation = mLidOpenRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) { - rotation = mCarDockRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { - rotation = mDeskDockRotation; - } - //if lid is closed orientation will be portrait + } + + void updateRotation(boolean alwaysSendConfiguration) { try { //set orientation on WindowManager - mWindowManager.setRotation(rotation, true, - mFancyRotationAnimation | animFlags); + mWindowManager.updateRotation(alwaysSendConfiguration); } catch (RemoteException e) { // Ignore } diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 9ebdd52ad47d..105e603769fe 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -4849,15 +4849,14 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public void verifyPendingInstall(int id, boolean verified, String message) + public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, null); final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); msg.arg1 = id; - msg.arg2 = verified ? 1 : 0; - msg.obj = message; + msg.arg2 = verificationCode; mHandler.sendMessage(msg); } diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java index dd440bf00d1e..f2e7485895fe 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/java/com/android/server/wm/DragState.java @@ -125,6 +125,12 @@ class DragState { mDragWindowHandle.frameTop = 0; mDragWindowHandle.frameRight = mService.mCurDisplayWidth; mDragWindowHandle.frameBottom = mService.mCurDisplayHeight; + + // Pause rotations before a drag. + if (WindowManagerService.DEBUG_ORIENTATION) { + Slog.d(WindowManagerService.TAG, "Pausing rotation during drag"); + } + mService.pauseRotationLocked(); } } @@ -142,6 +148,12 @@ class DragState { mDragWindowHandle = null; mDragApplicationHandle = null; + + // Resume rotations after a drag. + if (WindowManagerService.DEBUG_ORIENTATION) { + Slog.d(WindowManagerService.TAG, "Resuming rotation after drag"); + } + mService.resumeRotationLocked(); } } @@ -257,13 +269,6 @@ class DragState { // free our resources and drop all the object references mService.mDragState.reset(); mService.mDragState = null; - - if (WindowManagerService.DEBUG_ORIENTATION) Slog.d(WindowManagerService.TAG, "Performing post-drag rotation"); - boolean changed = mService.setRotationUncheckedLocked( - WindowManagerPolicy.USE_LAST_ROTATION, 0, false); - if (changed) { - mService.mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); - } } void notifyMoveLw(float x, float y) { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index ff75cfda118d..02b246ae3292 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -427,14 +427,11 @@ public class WindowManagerService extends IWindowManager.Stub int mAppDisplayWidth = 0; int mAppDisplayHeight = 0; int mRotation = 0; - int mRequestedRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean mAltOrientation = false; - int mLastRotationFlags; ArrayList<IRotationWatcher> mRotationWatchers = new ArrayList<IRotationWatcher>(); - int mDeferredRotation; - int mDeferredRotationAnimFlags; + int mDeferredRotationPauseCount; boolean mLayoutNeeded = true; boolean mAnimationPending = false; @@ -3414,9 +3411,7 @@ public class WindowManagerService extends IWindowManager.Stub //send a message to Policy indicating orientation change to take //action like disabling/enabling sensors etc., mPolicy.setCurrentOrientationLw(req); - if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION, - mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE, - inTransaction)) { + if (updateRotationUncheckedLocked(inTransaction)) { changed = true; } } @@ -4823,8 +4818,7 @@ public class WindowManagerService extends IWindowManager.Stub mPolicy.enableScreenAfterBoot(); // Make sure the last requested orientation has been applied. - setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, - mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); + updateRotationUnchecked(false); } public void showBootMessage(final CharSequence msg, final boolean always) { @@ -5043,6 +5037,10 @@ public class WindowManagerService extends IWindowManager.Stub return bm; } + /** + * Freeze rotation changes. (Enable "rotation lock".) + * Persists across reboots. + */ public void freezeRotation() { if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, "freezeRotation()")) { @@ -5052,9 +5050,13 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation); mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation); - setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0); + updateRotationUnchecked(false); } + /** + * Thaw rotation changes. (Disable "rotation lock".) + * Persists across reboots. + */ public void thawRotation() { if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, "thawRotation()")) { @@ -5064,30 +5066,56 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation); mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used - setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0); + updateRotationUnchecked(false); } - public void setRotation(int rotation, - boolean alwaysSendConfiguration, int animFlags) { - if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, - "setRotation()")) { - throw new SecurityException("Requires SET_ORIENTATION permission"); - } + /** + * Recalculate the current rotation. + * + * Called by the window manager policy whenever the state of the system changes + * such that the current rotation might need to be updated, such as when the + * device is docked or rotated into a new posture. + */ + public void updateRotation(boolean alwaysSendConfiguration) { + updateRotationUnchecked(alwaysSendConfiguration); + } - setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags); + /** + * Temporarily pauses rotation changes until resumed. + * + * This can be used to prevent rotation changes from occurring while the user is + * performing certain operations, such as drag and drop. + * + * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}. + */ + void pauseRotationLocked() { + mDeferredRotationPauseCount += 1; + } + + /** + * Resumes normal rotation changes after being paused. + */ + void resumeRotationLocked() { + if (mDeferredRotationPauseCount > 0) { + mDeferredRotationPauseCount -= 1; + if (mDeferredRotationPauseCount == 0) { + boolean changed = updateRotationUncheckedLocked(false); + if (changed) { + mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); + } + } + } } - public void setRotationUnchecked(int rotation, - boolean alwaysSendConfiguration, int animFlags) { - if(DEBUG_ORIENTATION) Slog.v(TAG, - "setRotationUnchecked(rotation=" + rotation + - " alwaysSendConfiguration=" + alwaysSendConfiguration + - " animFlags=" + animFlags); + public void updateRotationUnchecked( + boolean alwaysSendConfiguration) { + if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked(" + + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")"); long origId = Binder.clearCallingIdentity(); boolean changed; synchronized(mWindowMap) { - changed = setRotationUncheckedLocked(rotation, animFlags, false); + changed = updateRotationUncheckedLocked(false); } if (changed || alwaysSendConfiguration) { @@ -5098,152 +5126,113 @@ public class WindowManagerService extends IWindowManager.Stub } /** - * Apply a new rotation to the screen, respecting the requests of - * applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply - * re-evaluate the desired rotation. - * - * Returns null if the rotation has been changed. In this case YOU - * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN. + * Updates the current rotation. + * + * Returns true if the rotation has been changed. In this case YOU + * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN. */ - public boolean setRotationUncheckedLocked(int rotation, int animFlags, boolean inTransaction) { - if (mDragState != null - || (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating())) { - // Potential rotation during a drag or while waiting for a previous orientation - // change to finish (rotation animation will be dismissed). - // Don't do the rotation now, but make a note to perform the rotation later. - if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation."); - if (rotation != WindowManagerPolicy.USE_LAST_ROTATION) { - mDeferredRotation = rotation; - mDeferredRotationAnimFlags = animFlags; - } + public boolean updateRotationUncheckedLocked(boolean inTransaction) { + if (mDeferredRotationPauseCount > 0) { + // Rotation updates have been paused temporarily. Defer the update until + // updates have been resumed. + if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused."); return false; } - boolean changed; - if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) { - if (mDeferredRotation != WindowManagerPolicy.USE_LAST_ROTATION) { - rotation = mDeferredRotation; - mRequestedRotation = rotation; - mLastRotationFlags = mDeferredRotationAnimFlags; - } - rotation = mRequestedRotation; - } else { - mRequestedRotation = rotation; - mLastRotationFlags = animFlags; - } - mDeferredRotation = WindowManagerPolicy.USE_LAST_ROTATION; - if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation); - rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, - mRotation, mDisplayEnabled); - if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation); - - int desiredRotation = rotation; - int lockedRotation = mPolicy.getLockedRotationLw(); - if (lockedRotation >= 0 && rotation != lockedRotation) { - // We are locked in a rotation but something is requesting - // a different rotation... we will either keep the locked - // rotation if it results in the same orientation, or have to - // switch into an emulated orientation mode. - - // First, we know that our rotation is actually going to be - // the locked rotation. - rotation = lockedRotation; - - // Now the difference between the desired and lockedRotation - // may mean that the orientation is different... if that is - // not the case, we can just make the desired rotation be the - // same as the new locked rotation. - switch (lockedRotation) { - case Surface.ROTATION_0: - if (rotation == Surface.ROTATION_180) { - desiredRotation = lockedRotation; - } - break; - case Surface.ROTATION_90: - if (rotation == Surface.ROTATION_270) { - desiredRotation = lockedRotation; - } - break; - case Surface.ROTATION_180: - if (rotation == Surface.ROTATION_0) { - desiredRotation = lockedRotation; - } - break; - case Surface.ROTATION_270: - if (rotation == Surface.ROTATION_90) { - desiredRotation = lockedRotation; - } - break; - } + if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) { + // Rotation updates cannot be performed while the previous rotation change + // animation is still in progress. Skip this update. We will try updating + // again after the animation is finished and the display is unfrozen. + if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress."); + return false; } - changed = mDisplayEnabled && mRotation != rotation; - if (mAltOrientation != (rotation != desiredRotation)) { - changed = true; - mAltOrientation = rotation != desiredRotation; + if (!mDisplayEnabled) { + // No point choosing a rotation if the display is not enabled. + if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled."); + return false; } - if (changed) { - if (DEBUG_ORIENTATION) Slog.v(TAG, - "Rotation changed to " + rotation - + " from " + mRotation - + " (forceApp=" + mForcedAppOrientation - + ", req=" + mRequestedRotation + ")"); - mRotation = rotation; - mWindowsFreezingScreen = true; - mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); - mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), - 2000); - mWaitingForConfig = true; - mLayoutNeeded = true; - startFreezingDisplayLocked(inTransaction); - //Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags); - mInputManager.setDisplayOrientation(0, rotation); - if (mDisplayEnabled) { - // NOTE: We disable the rotation in the emulator because - // it doesn't support hardware OpenGL emulation yet. - if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null - && mScreenRotationAnimation.hasScreenshot()) { - Surface.freezeDisplay(0); - if (!inTransaction) { - if (SHOW_TRANSACTIONS) Slog.i(TAG, - ">>> OPEN TRANSACTION setRotationUnchecked"); - Surface.openTransaction(); - } - try { - if (mScreenRotationAnimation != null) { - mScreenRotationAnimation.setRotation(rotation); - } - } finally { - if (!inTransaction) { - Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(TAG, - "<<< CLOSE TRANSACTION setRotationUnchecked"); - } - } - Surface.setOrientation(0, rotation, animFlags); - Surface.unfreezeDisplay(0); - } else { - Surface.setOrientation(0, rotation, animFlags); - } - rebuildBlackFrame(inTransaction); - } + // TODO: Implement forced rotation changes. + // Set mAltOrientation to indicate that the application is receiving + // an orientation that has different metrics than it expected. + // eg. Portrait instead of Landscape. - for (int i=mWindows.size()-1; i>=0; i--) { - WindowState w = mWindows.get(i); - if (w.mSurface != null) { - w.mOrientationChanging = true; - } + int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation); + boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw( + mForcedAppOrientation, rotation); + + if (DEBUG_ORIENTATION) { + Slog.v(TAG, "Application requested orientation " + + mForcedAppOrientation + ", got rotation " + rotation + + " which has " + (altOrientation ? "incompatible" : "compatible") + + " metrics"); + } + + if (mRotation == rotation && mAltOrientation == altOrientation) { + // No change. + return false; + } + + if (DEBUG_ORIENTATION) { + Slog.v(TAG, + "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "") + + " from " + mRotation + (mAltOrientation ? " (alt)" : "") + + ", forceApp=" + mForcedAppOrientation); + } + + mRotation = rotation; + mAltOrientation = altOrientation; + + mWindowsFreezingScreen = true; + mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); + mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000); + mWaitingForConfig = true; + mLayoutNeeded = true; + startFreezingDisplayLocked(inTransaction); + mInputManager.setDisplayOrientation(0, rotation); + + // NOTE: We disable the rotation in the emulator because + // it doesn't support hardware OpenGL emulation yet. + if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null + && mScreenRotationAnimation.hasScreenshot()) { + Surface.freezeDisplay(0); + if (!inTransaction) { + if (SHOW_TRANSACTIONS) Slog.i(TAG, + ">>> OPEN TRANSACTION setRotationUnchecked"); + Surface.openTransaction(); } - for (int i=mRotationWatchers.size()-1; i>=0; i--) { - try { - mRotationWatchers.get(i).onRotationChanged(rotation); - } catch (RemoteException e) { + try { + if (mScreenRotationAnimation != null) { + mScreenRotationAnimation.setRotation(rotation); + } + } finally { + if (!inTransaction) { + Surface.closeTransaction(); + if (SHOW_TRANSACTIONS) Slog.i(TAG, + "<<< CLOSE TRANSACTION setRotationUnchecked"); } } - } //end if changed + Surface.setOrientation(0, rotation); + Surface.unfreezeDisplay(0); + } else { + Surface.setOrientation(0, rotation); + } + rebuildBlackFrame(inTransaction); - return changed; + for (int i=mWindows.size()-1; i>=0; i--) { + WindowState w = mWindows.get(i); + if (w.mSurface != null) { + w.mOrientationChanging = true; + } + } + for (int i=mRotationWatchers.size()-1; i>=0; i--) { + try { + mRotationWatchers.get(i).onRotationChanged(rotation); + } catch (RemoteException e) { + } + } + return true; } public int getRotation() { @@ -8601,8 +8590,7 @@ public class WindowManagerService extends IWindowManager.Stub if (updateRotation) { if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); - boolean changed = setRotationUncheckedLocked( - WindowManagerPolicy.USE_LAST_ROTATION, 0, false); + boolean changed = updateRotationUncheckedLocked(false); if (changed) { mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); } else { @@ -9029,8 +9017,7 @@ public class WindowManagerService extends IWindowManager.Stub if (updateRotation) { if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); - configChanged |= setRotationUncheckedLocked( - WindowManagerPolicy.USE_LAST_ROTATION, 0, false); + configChanged |= updateRotationUncheckedLocked(false); } if (configChanged) { @@ -9403,12 +9390,10 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen); pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig); pw.print(" mRotation="); pw.print(mRotation); - pw.print(" mRequestedRotation="); pw.print(mRequestedRotation); pw.print(" mAltOrientation="); pw.println(mAltOrientation); pw.print(" mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation); pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation); - pw.print(" mDeferredRotation="); pw.print(mDeferredRotation); - pw.print(", mDeferredRotationAnimFlags="); pw.println(mDeferredRotationAnimFlags); + pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount); pw.print(" mAnimationPending="); pw.print(mAnimationPending); pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale); pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0ef03bb7dde8..09097eea8ee2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -566,7 +566,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) const int dpy = 0; const int orientation = mCurrentState.orientation; - const uint32_t type = mCurrentState.orientationType; + // Currently unused: const uint32_t flags = mCurrentState.orientationFlags; GraphicPlane& plane(graphicPlane(dpy)); plane.setOrientation(orientation); @@ -1299,7 +1299,7 @@ int SurfaceFlinger::setOrientation(DisplayID dpy, Mutex::Autolock _l(mStateLock); if (mCurrentState.orientation != orientation) { if (uint32_t(orientation)<=eOrientation270 || orientation==42) { - mCurrentState.orientationType = flags; + mCurrentState.orientationFlags = flags; mCurrentState.orientation = orientation; setTransactionFlags(eTransactionNeeded); mTransactionCV.wait(mStateLock); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d7f005f7cefe..43191b7e8a54 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -245,7 +245,7 @@ private: } LayerVector layersSortedByZ; uint8_t orientation; - uint8_t orientationType; + uint8_t orientationFlags; uint8_t freezeDisplay; }; diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index f2fb36f497f9..3525abe4f863 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -546,11 +546,8 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } - /** - * @hide - */ @Override - public void verifyPendingInstall(int id, boolean verified, String failureMessage) { + public void verifyPendingInstall(int id, int verificationCode) { throw new UnsupportedOperationException(); } diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index f015378e2610..5df018e68eaf 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -412,9 +412,31 @@ public class WindowManagerPermissionTests extends TestCase { @SmallTest public void testSET_ORIENTATION() { try { - mWm.setRotation(0, true, 0); + mWm.updateRotation(true); mWm.getSwitchState(0); - fail("IWindowManager.setRotation did not throw SecurityException as" + fail("IWindowManager.updateRotation did not throw SecurityException as" + + " expected"); + } catch (SecurityException e) { + // expected + } catch (RemoteException e) { + fail("Unexpected remote exception"); + } + + try { + mWm.freezeRotation(); + mWm.getSwitchState(0); + fail("IWindowManager.freezeRotation did not throw SecurityException as" + + " expected"); + } catch (SecurityException e) { + // expected + } catch (RemoteException e) { + fail("Unexpected remote exception"); + } + + try { + mWm.thawRotation(); + mWm.getSwitchState(0); + fail("IWindowManager.thawRotation did not throw SecurityException as" + " expected"); } catch (SecurityException e) { // expected diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java index 3d1fa7aed622..940b290cffd1 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java @@ -396,7 +396,7 @@ public class BridgeWindowManager implements IWindowManager { } - public void setRotation(int arg0, boolean arg1, int arg2) throws RemoteException { + public void updateRotation(boolean arg0) throws RemoteException { // TODO Auto-generated method stub } |