Merge "Relax form autocomplete conditions"
diff --git a/api/current.txt b/api/current.txt
index d91a887..950a4aa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -644,6 +644,8 @@
field public static final int listPreferredItemHeight = 16842829; // 0x101004d
field public static final int listPreferredItemHeightLarge = 16843668; // 0x1010394
field public static final int listPreferredItemHeightSmall = 16843669; // 0x1010395
+ field public static final int listPreferredItemPaddingLeft = 16843697; // 0x10103b1
+ field public static final int listPreferredItemPaddingRight = 16843698; // 0x10103b2
field public static final int listSelector = 16843003; // 0x10100fb
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
@@ -2075,7 +2077,8 @@
method public android.accounts.Account[] getAccountsByType(java.lang.String);
method public android.accounts.AccountManagerFuture<android.accounts.Account[]> getAccountsByTypeAndFeatures(java.lang.String, java.lang.String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
- method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+ method public deprecated android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+ method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
method public java.lang.String getPassword(android.accounts.Account);
@@ -2104,6 +2107,7 @@
field public static final java.lang.String KEY_ACCOUNT_MANAGER_RESPONSE = "accountManagerResponse";
field public static final java.lang.String KEY_ACCOUNT_NAME = "authAccount";
field public static final java.lang.String KEY_ACCOUNT_TYPE = "accountType";
+ field public static final java.lang.String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
field public static final java.lang.String KEY_AUTHENTICATOR_TYPES = "authenticator_types";
field public static final java.lang.String KEY_AUTHTOKEN = "authtoken";
field public static final java.lang.String KEY_AUTH_FAILED_MESSAGE = "authFailedMessage";
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 2156425..029d107 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -197,6 +197,16 @@
public static final String KEY_CALLER_PID = "callerPid";
/**
+ * The Android package of the caller will be set in the options bundle by the
+ * {@link AccountManager} and will be passed to the AccountManagerService and
+ * to the AccountAuthenticators. The uid of the caller will be known by the
+ * AccountManagerService as well as the AccountAuthenticators so they will be able to
+ * verify that the package is consistent with the uid (a uid might be shared by many
+ * packages).
+ */
+ public static final String KEY_ANDROID_PACKAGE_NAME = "androidPackageName";
+
+ /**
* Boolean, if set and 'customTokens' the authenticator is responsible for
* notifications.
* @hide
@@ -880,7 +890,10 @@
* If the account is no longer present on the device, the return value is
* authenticator-dependent. The caller should verify the validity of the
* account before requesting an auth token.
+ * @deprecated use {@link #getAuthToken(Account, String, android.os.Bundle,
+ * boolean, AccountManagerCallback, android.os.Handler)} instead
*/
+ @Deprecated
public AccountManagerFuture<Bundle> getAuthToken(
final Account account, final String authTokenType, final boolean notifyAuthFailure,
AccountManagerCallback<Bundle> callback, Handler handler) {
@@ -895,6 +908,90 @@
}
/**
+ * Gets an auth token of the specified type for a particular account,
+ * optionally raising a notification if the user must enter credentials.
+ * This method is intended for background tasks and services where the
+ * user should not be immediately interrupted with a password prompt.
+ *
+ * <p>If a previously generated auth token is cached for this account and
+ * type, then it is returned. Otherwise, if a saved password is
+ * available, it is sent to the server to generate a new auth token.
+ * Otherwise, an {@link Intent} is returned which, when started, will
+ * prompt the user for a password. If the notifyAuthFailure parameter is
+ * set, a status bar notification is also created with the same Intent,
+ * alerting the user that they need to enter a password at some point.
+ *
+ * <p>In that case, you may need to wait until the user responds, which
+ * could take hours or days or forever. When the user does respond and
+ * supply a new password, the account manager will broadcast the
+ * {@link #LOGIN_ACCOUNTS_CHANGED_ACTION} Intent, which applications can
+ * use to try again.
+ *
+ * <p>If notifyAuthFailure is not set, it is the application's
+ * responsibility to launch the returned Intent at some point.
+ * Either way, the result from this call will not wait for user action.
+ *
+ * <p>Some authenticators have auth token <em>types</em>, whose value
+ * is authenticator-dependent. Some services use different token types to
+ * access different functionality -- for example, Google uses different auth
+ * tokens to access Gmail and Google Calendar for the same account.
+ *
+ * <p>This method may be called from any thread, but the returned
+ * {@link AccountManagerFuture} must not be used on the main thread.
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#USE_CREDENTIALS}.
+ *
+ * @param account The account to fetch an auth token for
+ * @param authTokenType The auth token type, an authenticator-dependent
+ * string token, must not be null
+ * @param options Authenticator-specific options for the request,
+ * may be null or empty
+ * @param notifyAuthFailure True to add a notification to prompt the
+ * user for a password if necessary, false to leave that to the caller
+ * @param callback Callback to invoke when the request completes,
+ * null for no callback
+ * @param handler {@link Handler} identifying the callback thread,
+ * null for the main thread
+ * @return An {@link AccountManagerFuture} which resolves to a Bundle with
+ * at least the following fields on success:
+ * <ul>
+ * <li> {@link #KEY_ACCOUNT_NAME} - the name of the account you supplied
+ * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
+ * <li> {@link #KEY_AUTHTOKEN} - the auth token you wanted
+ * </ul>
+ *
+ * (Other authenticator-specific values may be returned.) If the user
+ * must enter credentials, the returned Bundle contains only
+ * {@link #KEY_INTENT} with the {@link Intent} needed to launch a prompt.
+ *
+ * If an error occurred, {@link AccountManagerFuture#getResult()} throws:
+ * <ul>
+ * <li> {@link AuthenticatorException} if the authenticator failed to respond
+ * <li> {@link OperationCanceledException} if the operation is canceled for
+ * any reason, incluidng the user canceling a credential request
+ * <li> {@link IOException} if the authenticator experienced an I/O problem
+ * creating a new auth token, usually because of network trouble
+ * </ul>
+ * If the account is no longer present on the device, the return value is
+ * authenticator-dependent. The caller should verify the validity of the
+ * account before requesting an auth token.
+ */
+ public AccountManagerFuture<Bundle> getAuthToken(
+ final Account account, final String authTokenType,
+ final Bundle options, final boolean notifyAuthFailure,
+ AccountManagerCallback<Bundle> callback, Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
+ return new AmsTask(null, handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.getAuthToken(mResponse, account, authTokenType,
+ notifyAuthFailure, false /* expectActivityLaunch */, options);
+ }
+ }.start();
+ }
+
+ /**
* Asks the user to add an account of a specified type. The authenticator
* for this account type processes this request with the appropriate user
* interface. If the user does elect to create a new account, the account
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index c165d92..9b2b8ca 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -81,6 +81,20 @@
*/
public static final int CHANNEL_TYPE_ANY = 12;
+ /** @hide */
+ public static final int HEALTH_OPERATION_SUCCESS = 6000;
+ /** @hide */
+ public static final int HEALTH_OPERATION_ERROR = 6001;
+ /** @hide */
+ public static final int HEALTH_OPERATION_INVALID_ARGS = 6002;
+ /** @hide */
+ public static final int HEALTH_OPERATION_GENERIC_FAILURE = 6003;
+ /** @hide */
+ public static final int HEALTH_OPERATION_NOT_FOUND = 6004;
+ /** @hide */
+ public static final int HEALTH_OPERATION_NOT_ALLOWED = 6005;
+
+
/**
* Register an application configuration that acts as a Health SINK.
* This is the configuration that will be used to communicate with health devices
diff --git a/core/java/android/provider/SyncStateContract.java b/core/java/android/provider/SyncStateContract.java
index e8177ca..f1189e4 100644
--- a/core/java/android/provider/SyncStateContract.java
+++ b/core/java/android/provider/SyncStateContract.java
@@ -74,6 +74,12 @@
Account account) throws RemoteException {
Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
new String[]{account.name, account.type}, null);
+
+ // Unable to query the provider
+ if (c == null) {
+ throw new RemoteException();
+ }
+
try {
if (c.moveToNext()) {
return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
@@ -123,6 +129,11 @@
Account account) throws RemoteException {
Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
new String[]{account.name, account.type}, null);
+
+ if (c == null) {
+ throw new RemoteException();
+ }
+
try {
if (c.moveToNext()) {
long rowId = c.getLong(1);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e4f2d32..56da69d 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -20,6 +20,7 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHealth;
import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
@@ -974,6 +975,22 @@
}
/**
+ * Called by native code for the async response to a Connect
+ * method call to org.bluez.Health
+ *
+ * @param chanCode The internal id of the channel
+ * @param result Result code of the operation.
+ */
+ private void onHealthDeviceConnectionResult(int chanCode, int result) {
+ log ("onHealthDeviceConnectionResult " + chanCode + " " + result);
+ // Success case gets handled by Property Change signal
+ if (result != BluetoothHealth.HEALTH_OPERATION_SUCCESS) {
+ mBluetoothService.onHealthDeviceChannelConnectionError(chanCode,
+ BluetoothHealth.STATE_CHANNEL_DISCONNECTED);
+ }
+ }
+
+ /**
* Called by native code on a DeviceDisconnected signal from
* org.bluez.NetworkServer.
*
diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java
index a6ada2b..2d80de4 100644
--- a/core/java/android/server/BluetoothHealthProfileHandler.java
+++ b/core/java/android/server/BluetoothHealthProfileHandler.java
@@ -84,7 +84,6 @@
result = 31 * result + (mChannelPath == null ? 0 : mChannelPath.hashCode());
result = 31 * result + mDevice.hashCode();
result = 31 * result + mConfig.hashCode();
- result = 31 * result + mState;
result = 31 * result + mChannelType;
return result;
}
@@ -152,7 +151,7 @@
String channelType = getStringChannelType(chan.mChannelType);
if (!mBluetoothService.createChannelNative(deviceObjectPath, configPath,
- channelType)) {
+ channelType, chan.hashCode())) {
int prevState = chan.mState;
int state = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
callHealthChannelCallback(chan.mConfig, chan.mDevice, prevState, state, null,
@@ -258,7 +257,7 @@
boolean disconnectChannel(BluetoothDevice device,
BluetoothHealthAppConfiguration config, int id) {
- HealthChannel chan = findChannelById(device, config, id);
+ HealthChannel chan = findChannelById(id);
if (chan == null) {
return false;
}
@@ -273,7 +272,8 @@
callHealthChannelCallback(config, device, prevState, chan.mState,
null, chan.hashCode());
- if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath)) {
+ if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath,
+ chan.hashCode())) {
prevState = chan.mState;
chan.mState = BluetoothHealth.STATE_CHANNEL_CONNECTED;
callHealthChannelCallback(config, device, prevState, chan.mState,
@@ -284,8 +284,7 @@
}
}
- private HealthChannel findChannelById(BluetoothDevice device,
- BluetoothHealthAppConfiguration config, int id) {
+ private HealthChannel findChannelById(int id) {
for (HealthChannel chan : mHealthChannels) {
if (chan.hashCode() == id) return chan;
}
@@ -384,6 +383,15 @@
}
}
+ /*package*/ void onHealthDeviceChannelConnectionError(int chanCode,
+ int state) {
+ HealthChannel channel = findChannelById(chanCode);
+ if (channel == null) errorLog("No record of this channel:" + chanCode);
+
+ callHealthChannelCallback(channel.mConfig, channel.mDevice, channel.mState, state, null,
+ chanCode);
+ }
+
private BluetoothHealthAppConfiguration findHealthApplication(
BluetoothDevice device, String channelPath) {
BluetoothHealthAppConfiguration config = null;
@@ -424,9 +432,19 @@
config = findHealthApplication(device, channelPath);
if (exists) {
+ channel = findConnectingChannel(device, config);
+ if (channel == null) {
+ channel = new HealthChannel(device, config, null, false,
+ channelPath);
+ channel.mState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
+ mHealthChannels.add(channel);
+ }
+ channel.mChannelPath = channelPath;
+
fd = mBluetoothService.getChannelFdNative(channelPath);
if (fd == null) {
errorLog("Error obtaining fd for channel:" + channelPath);
+ disconnectChannel(device, config, channel.hashCode());
return;
}
boolean mainChannel =
@@ -440,18 +458,10 @@
}
if (mainChannelPath.equals(channelPath)) mainChannel = true;
}
- channel = findConnectingChannel(device, config);
- if (channel != null) {
- channel.mChannelFd = fd;
- channel.mMainChannel = mainChannel;
- channel.mChannelPath = channelPath;
- prevState = channel.mState;
- } else {
- channel = new HealthChannel(device, config, fd, mainChannel,
- channelPath);
- mHealthChannels.add(channel);
- prevState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
- }
+
+ channel.mChannelFd = fd;
+ channel.mMainChannel = mainChannel;
+ prevState = channel.mState;
state = BluetoothHealth.STATE_CHANNEL_CONNECTED;
} else {
channel = findChannelByPath(device, channelPath);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 03180ca..00d3331 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2255,6 +2255,14 @@
}
}
+ /*package*/ void onHealthDeviceChannelConnectionError(int channelCode,
+ int newState) {
+ synchronized(mBluetoothHealthProfileHandler) {
+ mBluetoothHealthProfileHandler.onHealthDeviceChannelConnectionError(channelCode,
+ newState);
+ }
+ }
+
public int getHealthDeviceConnectionState(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
"Need BLUETOOTH permission");
@@ -2785,8 +2793,9 @@
String channelType);
native String registerHealthApplicationNative(int dataType, String role, String name);
native boolean unregisterHealthApplicationNative(String path);
- native boolean createChannelNative(String devicePath, String appPath, String channelType);
- native boolean destroyChannelNative(String devicePath, String channelpath);
+ native boolean createChannelNative(String devicePath, String appPath, String channelType,
+ int code);
+ native boolean destroyChannelNative(String devicePath, String channelpath, int code);
native String getMainChannelNative(String path);
native String getChannelApplicationNative(String channelPath);
native ParcelFileDescriptor getChannelFdNative(String channelPath);
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 39f9367..713bb91 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -36,6 +36,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
@@ -716,7 +717,9 @@
mSession = ViewRootImpl.getWindowSession(getMainLooper());
mWindow.setSession(mSession);
-
+
+ mScreenOn = ((PowerManager)getSystemService(Context.POWER_SERVICE)).isScreenOn();
+
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
diff --git a/core/java/android/text/style/SuggestionRangeSpan.java b/core/java/android/text/style/SuggestionRangeSpan.java
index a637b1c..2dbfc72 100644
--- a/core/java/android/text/style/SuggestionRangeSpan.java
+++ b/core/java/android/text/style/SuggestionRangeSpan.java
@@ -28,15 +28,11 @@
* @hide
*/
public class SuggestionRangeSpan extends CharacterStyle implements ParcelableSpan {
- private final int mBackgroundColor;
+ private int mBackgroundColor;
- @Override
- public void updateDrawState(TextPaint tp) {
- tp.bgColor = mBackgroundColor;
- }
-
- public SuggestionRangeSpan(int color) {
- mBackgroundColor = color;
+ public SuggestionRangeSpan() {
+ // 0 is a fully transparent black. Has to be set using #setBackgroundColor
+ mBackgroundColor = 0;
}
public SuggestionRangeSpan(Parcel src) {
@@ -57,4 +53,13 @@
public int getSpanTypeId() {
return TextUtils.SUGGESTION_RANGE_SPAN;
}
+
+ public void setBackgroundColor(int backgroundColor) {
+ mBackgroundColor = backgroundColor;
+ }
+
+ @Override
+ public void updateDrawState(TextPaint tp) {
+ tp.bgColor = mBackgroundColor;
+ }
}
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 693a7a9..fecf0f7 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -264,4 +264,14 @@
tp.setUnderlineText(mEasyCorrectUnderlineColor, mEasyCorrectUnderlineThickness);
}
}
+
+ /**
+ * @return The color of the underline for that span, or 0 if there is no underline
+ */
+ public int getUnderlineColor() {
+ // The order here should match what is used in updateDrawState
+ if ((mFlags & FLAG_MISSPELLED) != 0) return mMisspelledUnderlineColor;
+ if ((mFlags & FLAG_EASY_CORRECT) != 0) return mEasyCorrectUnderlineColor;
+ return 0;
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4a9c5bd..7a35015 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -27,6 +27,7 @@
import android.graphics.Interpolator;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
+import android.graphics.Matrix.ScaleToFit;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -2001,64 +2002,133 @@
@ViewDebug.ExportedProperty
int mViewFlags;
- /**
- * The transform matrix for the View. This transform is calculated internally
- * based on the rotation, scaleX, and scaleY properties. The identity matrix
- * is used by default. Do *not* use this variable directly; instead call
- * getMatrix(), which will automatically recalculate the matrix if necessary
- * to get the correct matrix based on the latest rotation and scale properties.
- */
- private final Matrix mMatrix = new Matrix();
+ static class TransformationInfo {
+ /**
+ * The transform matrix for the View. This transform is calculated internally
+ * based on the rotation, scaleX, and scaleY properties. The identity matrix
+ * is used by default. Do *not* use this variable directly; instead call
+ * getMatrix(), which will automatically recalculate the matrix if necessary
+ * to get the correct matrix based on the latest rotation and scale properties.
+ */
+ private final Matrix mMatrix = new Matrix();
- /**
- * The transform matrix for the View. This transform is calculated internally
- * based on the rotation, scaleX, and scaleY properties. The identity matrix
- * is used by default. Do *not* use this variable directly; instead call
- * getInverseMatrix(), which will automatically recalculate the matrix if necessary
- * to get the correct matrix based on the latest rotation and scale properties.
- */
- private Matrix mInverseMatrix;
+ /**
+ * The transform matrix for the View. This transform is calculated internally
+ * based on the rotation, scaleX, and scaleY properties. The identity matrix
+ * is used by default. Do *not* use this variable directly; instead call
+ * getInverseMatrix(), which will automatically recalculate the matrix if necessary
+ * to get the correct matrix based on the latest rotation and scale properties.
+ */
+ private Matrix mInverseMatrix;
- /**
- * An internal variable that tracks whether we need to recalculate the
- * transform matrix, based on whether the rotation or scaleX/Y properties
- * have changed since the matrix was last calculated.
- */
- boolean mMatrixDirty = false;
+ /**
+ * An internal variable that tracks whether we need to recalculate the
+ * transform matrix, based on whether the rotation or scaleX/Y properties
+ * have changed since the matrix was last calculated.
+ */
+ boolean mMatrixDirty = false;
- /**
- * An internal variable that tracks whether we need to recalculate the
- * transform matrix, based on whether the rotation or scaleX/Y properties
- * have changed since the matrix was last calculated.
- */
- private boolean mInverseMatrixDirty = true;
+ /**
+ * An internal variable that tracks whether we need to recalculate the
+ * transform matrix, based on whether the rotation or scaleX/Y properties
+ * have changed since the matrix was last calculated.
+ */
+ private boolean mInverseMatrixDirty = true;
- /**
- * A variable that tracks whether we need to recalculate the
- * transform matrix, based on whether the rotation or scaleX/Y properties
- * have changed since the matrix was last calculated. This variable
- * is only valid after a call to updateMatrix() or to a function that
- * calls it such as getMatrix(), hasIdentityMatrix() and getInverseMatrix().
- */
- private boolean mMatrixIsIdentity = true;
+ /**
+ * A variable that tracks whether we need to recalculate the
+ * transform matrix, based on whether the rotation or scaleX/Y properties
+ * have changed since the matrix was last calculated. This variable
+ * is only valid after a call to updateMatrix() or to a function that
+ * calls it such as getMatrix(), hasIdentityMatrix() and getInverseMatrix().
+ */
+ private boolean mMatrixIsIdentity = true;
- /**
- * The Camera object is used to compute a 3D matrix when rotationX or rotationY are set.
- */
- private Camera mCamera = null;
+ /**
+ * The Camera object is used to compute a 3D matrix when rotationX or rotationY are set.
+ */
+ private Camera mCamera = null;
- /**
- * This matrix is used when computing the matrix for 3D rotations.
- */
- private Matrix matrix3D = null;
+ /**
+ * This matrix is used when computing the matrix for 3D rotations.
+ */
+ private Matrix matrix3D = null;
- /**
- * These prev values are used to recalculate a centered pivot point when necessary. The
- * pivot point is only used in matrix operations (when rotation, scale, or translation are
- * set), so thes values are only used then as well.
- */
- private int mPrevWidth = -1;
- private int mPrevHeight = -1;
+ /**
+ * These prev values are used to recalculate a centered pivot point when necessary. The
+ * pivot point is only used in matrix operations (when rotation, scale, or translation are
+ * set), so thes values are only used then as well.
+ */
+ private int mPrevWidth = -1;
+ private int mPrevHeight = -1;
+
+ /**
+ * The degrees rotation around the vertical axis through the pivot point.
+ */
+ @ViewDebug.ExportedProperty
+ float mRotationY = 0f;
+
+ /**
+ * The degrees rotation around the horizontal axis through the pivot point.
+ */
+ @ViewDebug.ExportedProperty
+ float mRotationX = 0f;
+
+ /**
+ * The degrees rotation around the pivot point.
+ */
+ @ViewDebug.ExportedProperty
+ float mRotation = 0f;
+
+ /**
+ * The amount of translation of the object away from its left property (post-layout).
+ */
+ @ViewDebug.ExportedProperty
+ float mTranslationX = 0f;
+
+ /**
+ * The amount of translation of the object away from its top property (post-layout).
+ */
+ @ViewDebug.ExportedProperty
+ float mTranslationY = 0f;
+
+ /**
+ * The amount of scale in the x direction around the pivot point. A
+ * value of 1 means no scaling is applied.
+ */
+ @ViewDebug.ExportedProperty
+ float mScaleX = 1f;
+
+ /**
+ * The amount of scale in the y direction around the pivot point. A
+ * value of 1 means no scaling is applied.
+ */
+ @ViewDebug.ExportedProperty
+ float mScaleY = 1f;
+
+ /**
+ * The amount of scale in the x direction around the pivot point. A
+ * value of 1 means no scaling is applied.
+ */
+ @ViewDebug.ExportedProperty
+ float mPivotX = 0f;
+
+ /**
+ * The amount of scale in the y direction around the pivot point. A
+ * value of 1 means no scaling is applied.
+ */
+ @ViewDebug.ExportedProperty
+ float mPivotY = 0f;
+
+ /**
+ * The opacity of the View. This is a value from 0 to 1, where 0 means
+ * completely transparent and 1 means completely opaque.
+ */
+ @ViewDebug.ExportedProperty
+ float mAlpha = 1f;
+ }
+
+ TransformationInfo mTransformationInfo;
private boolean mLastIsOpaque;
@@ -2069,71 +2139,6 @@
private static final float NONZERO_EPSILON = .001f;
/**
- * The degrees rotation around the vertical axis through the pivot point.
- */
- @ViewDebug.ExportedProperty
- float mRotationY = 0f;
-
- /**
- * The degrees rotation around the horizontal axis through the pivot point.
- */
- @ViewDebug.ExportedProperty
- float mRotationX = 0f;
-
- /**
- * The degrees rotation around the pivot point.
- */
- @ViewDebug.ExportedProperty
- float mRotation = 0f;
-
- /**
- * The amount of translation of the object away from its left property (post-layout).
- */
- @ViewDebug.ExportedProperty
- float mTranslationX = 0f;
-
- /**
- * The amount of translation of the object away from its top property (post-layout).
- */
- @ViewDebug.ExportedProperty
- float mTranslationY = 0f;
-
- /**
- * The amount of scale in the x direction around the pivot point. A
- * value of 1 means no scaling is applied.
- */
- @ViewDebug.ExportedProperty
- float mScaleX = 1f;
-
- /**
- * The amount of scale in the y direction around the pivot point. A
- * value of 1 means no scaling is applied.
- */
- @ViewDebug.ExportedProperty
- float mScaleY = 1f;
-
- /**
- * The amount of scale in the x direction around the pivot point. A
- * value of 1 means no scaling is applied.
- */
- @ViewDebug.ExportedProperty
- float mPivotX = 0f;
-
- /**
- * The amount of scale in the y direction around the pivot point. A
- * value of 1 means no scaling is applied.
- */
- @ViewDebug.ExportedProperty
- float mPivotY = 0f;
-
- /**
- * The opacity of the View. This is a value from 0 to 1, where 0 means
- * completely transparent and 1 means completely opaque.
- */
- @ViewDebug.ExportedProperty
- float mAlpha = 1f;
-
- /**
* The distance in pixels from the left edge of this view's parent
* to the left edge of this view.
* {@hide}
@@ -6776,8 +6781,11 @@
* @return The current transform matrix for the view
*/
public Matrix getMatrix() {
- updateMatrix();
- return mMatrix;
+ if (mTransformationInfo != null) {
+ updateMatrix();
+ return mTransformationInfo.mMatrix;
+ }
+ return Matrix.IDENTITY_MATRIX;
}
/**
@@ -6797,49 +6805,63 @@
* @return True if the transform matrix is the identity matrix, false otherwise.
*/
final boolean hasIdentityMatrix() {
- updateMatrix();
- return mMatrixIsIdentity;
+ if (mTransformationInfo != null) {
+ updateMatrix();
+ return mTransformationInfo.mMatrixIsIdentity;
+ }
+ return true;
+ }
+
+ void ensureTransformationInfo() {
+ if (mTransformationInfo == null) {
+ mTransformationInfo = new TransformationInfo();
+ }
}
/**
* Recomputes the transform matrix if necessary.
*/
private void updateMatrix() {
- if (mMatrixDirty) {
+ final TransformationInfo info = mTransformationInfo;
+ if (info == null) {
+ return;
+ }
+ if (info.mMatrixDirty) {
// transform-related properties have changed since the last time someone
// asked for the matrix; recalculate it with the current values
// Figure out if we need to update the pivot point
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
- if ((mRight - mLeft) != mPrevWidth || (mBottom - mTop) != mPrevHeight) {
- mPrevWidth = mRight - mLeft;
- mPrevHeight = mBottom - mTop;
- mPivotX = mPrevWidth / 2f;
- mPivotY = mPrevHeight / 2f;
+ if ((mRight - mLeft) != info.mPrevWidth || (mBottom - mTop) != info.mPrevHeight) {
+ info.mPrevWidth = mRight - mLeft;
+ info.mPrevHeight = mBottom - mTop;
+ info.mPivotX = info.mPrevWidth / 2f;
+ info.mPivotY = info.mPrevHeight / 2f;
}
}
- mMatrix.reset();
- if (!nonzero(mRotationX) && !nonzero(mRotationY)) {
- mMatrix.setTranslate(mTranslationX, mTranslationY);
- mMatrix.preRotate(mRotation, mPivotX, mPivotY);
- mMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+ info.mMatrix.reset();
+ if (!nonzero(info.mRotationX) && !nonzero(info.mRotationY)) {
+ info.mMatrix.setTranslate(info.mTranslationX, info.mTranslationY);
+ info.mMatrix.preRotate(info.mRotation, info.mPivotX, info.mPivotY);
+ info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY);
} else {
- if (mCamera == null) {
- mCamera = new Camera();
- matrix3D = new Matrix();
+ if (info.mCamera == null) {
+ info.mCamera = new Camera();
+ info.matrix3D = new Matrix();
}
- mCamera.save();
- mMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
- mCamera.rotate(mRotationX, mRotationY, -mRotation);
- mCamera.getMatrix(matrix3D);
- matrix3D.preTranslate(-mPivotX, -mPivotY);
- matrix3D.postTranslate(mPivotX + mTranslationX, mPivotY + mTranslationY);
- mMatrix.postConcat(matrix3D);
- mCamera.restore();
+ info.mCamera.save();
+ info.mMatrix.preScale(info.mScaleX, info.mScaleY, info.mPivotX, info.mPivotY);
+ info.mCamera.rotate(info.mRotationX, info.mRotationY, -info.mRotation);
+ info.mCamera.getMatrix(info.matrix3D);
+ info.matrix3D.preTranslate(-info.mPivotX, -info.mPivotY);
+ info.matrix3D.postTranslate(info.mPivotX + info.mTranslationX,
+ info.mPivotY + info.mTranslationY);
+ info.mMatrix.postConcat(info.matrix3D);
+ info.mCamera.restore();
}
- mMatrixDirty = false;
- mMatrixIsIdentity = mMatrix.isIdentity();
- mInverseMatrixDirty = true;
+ info.mMatrixDirty = false;
+ info.mMatrixIsIdentity = info.mMatrix.isIdentity();
+ info.mInverseMatrixDirty = true;
}
}
@@ -6851,15 +6873,19 @@
* @return The inverse of the current matrix of this view.
*/
final Matrix getInverseMatrix() {
- updateMatrix();
- if (mInverseMatrixDirty) {
- if (mInverseMatrix == null) {
- mInverseMatrix = new Matrix();
+ final TransformationInfo info = mTransformationInfo;
+ if (info != null) {
+ updateMatrix();
+ if (info.mInverseMatrixDirty) {
+ if (info.mInverseMatrix == null) {
+ info.mInverseMatrix = new Matrix();
+ }
+ info.mMatrix.invert(info.mInverseMatrix);
+ info.mInverseMatrixDirty = false;
}
- mMatrix.invert(mInverseMatrix);
- mInverseMatrixDirty = false;
+ return info.mInverseMatrix;
}
- return mInverseMatrix;
+ return Matrix.IDENTITY_MATRIX;
}
/**
@@ -6905,14 +6931,16 @@
invalidateParentCaches();
invalidate(false);
+ ensureTransformationInfo();
final float dpi = mResources.getDisplayMetrics().densityDpi;
- if (mCamera == null) {
- mCamera = new Camera();
- matrix3D = new Matrix();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mCamera == null) {
+ info.mCamera = new Camera();
+ info.matrix3D = new Matrix();
}
- mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi);
- mMatrixDirty = true;
+ info.mCamera.setLocation(0.0f, 0.0f, -Math.abs(distance) / dpi);
+ info.mMatrixDirty = true;
invalidate(false);
}
@@ -6927,7 +6955,7 @@
* @return The degrees of rotation.
*/
public float getRotation() {
- return mRotation;
+ return mTransformationInfo != null ? mTransformationInfo.mRotation : 0;
}
/**
@@ -6945,12 +6973,14 @@
* @attr ref android.R.styleable#View_rotation
*/
public void setRotation(float rotation) {
- if (mRotation != rotation) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mRotation != rotation) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mRotation = rotation;
- mMatrixDirty = true;
+ info.mRotation = rotation;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -6966,7 +6996,7 @@
* @return The degrees of Y rotation.
*/
public float getRotationY() {
- return mRotationY;
+ return mTransformationInfo != null ? mTransformationInfo.mRotationY : 0;
}
/**
@@ -6989,12 +7019,14 @@
* @attr ref android.R.styleable#View_rotationY
*/
public void setRotationY(float rotationY) {
- if (mRotationY != rotationY) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mRotationY != rotationY) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mRotationY = rotationY;
- mMatrixDirty = true;
+ info.mRotationY = rotationY;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7010,7 +7042,7 @@
* @return The degrees of X rotation.
*/
public float getRotationX() {
- return mRotationX;
+ return mTransformationInfo != null ? mTransformationInfo.mRotationX : 0;
}
/**
@@ -7033,12 +7065,14 @@
* @attr ref android.R.styleable#View_rotationX
*/
public void setRotationX(float rotationX) {
- if (mRotationX != rotationX) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mRotationX != rotationX) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mRotationX = rotationX;
- mMatrixDirty = true;
+ info.mRotationX = rotationX;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7055,7 +7089,7 @@
* @return The scaling factor.
*/
public float getScaleX() {
- return mScaleX;
+ return mTransformationInfo != null ? mTransformationInfo.mScaleX : 1;
}
/**
@@ -7069,12 +7103,14 @@
* @attr ref android.R.styleable#View_scaleX
*/
public void setScaleX(float scaleX) {
- if (mScaleX != scaleX) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mScaleX != scaleX) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mScaleX = scaleX;
- mMatrixDirty = true;
+ info.mScaleX = scaleX;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7091,7 +7127,7 @@
* @return The scaling factor.
*/
public float getScaleY() {
- return mScaleY;
+ return mTransformationInfo != null ? mTransformationInfo.mScaleY : 1;
}
/**
@@ -7105,12 +7141,14 @@
* @attr ref android.R.styleable#View_scaleY
*/
public void setScaleY(float scaleY) {
- if (mScaleY != scaleY) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mScaleY != scaleY) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mScaleY = scaleY;
- mMatrixDirty = true;
+ info.mScaleY = scaleY;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7127,7 +7165,7 @@
* @return The x location of the pivot point.
*/
public float getPivotX() {
- return mPivotX;
+ return mTransformationInfo != null ? mTransformationInfo.mPivotX : 0;
}
/**
@@ -7146,13 +7184,15 @@
* @attr ref android.R.styleable#View_transformPivotX
*/
public void setPivotX(float pivotX) {
+ ensureTransformationInfo();
mPrivateFlags |= PIVOT_EXPLICITLY_SET;
- if (mPivotX != pivotX) {
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mPivotX != pivotX) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mPivotX = pivotX;
- mMatrixDirty = true;
+ info.mPivotX = pivotX;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7169,7 +7209,7 @@
* @return The y location of the pivot point.
*/
public float getPivotY() {
- return mPivotY;
+ return mTransformationInfo != null ? mTransformationInfo.mPivotY : 0;
}
/**
@@ -7187,13 +7227,15 @@
* @attr ref android.R.styleable#View_transformPivotY
*/
public void setPivotY(float pivotY) {
+ ensureTransformationInfo();
mPrivateFlags |= PIVOT_EXPLICITLY_SET;
- if (mPivotY != pivotY) {
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mPivotY != pivotY) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mPivotY = pivotY;
- mMatrixDirty = true;
+ info.mPivotY = pivotY;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7207,7 +7249,7 @@
* @return The opacity of the view.
*/
public float getAlpha() {
- return mAlpha;
+ return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
}
/**
@@ -7226,7 +7268,8 @@
* @attr ref android.R.styleable#View_alpha
*/
public void setAlpha(float alpha) {
- mAlpha = alpha;
+ ensureTransformationInfo();
+ mTransformationInfo.mAlpha = alpha;
invalidateParentCaches();
if (onSetAlpha((int) (alpha * 255))) {
mPrivateFlags |= ALPHA_SET;
@@ -7248,7 +7291,8 @@
* @return true if the View subclass handles alpha (the return value for onSetAlpha())
*/
boolean setAlphaNoInvalidation(float alpha) {
- mAlpha = alpha;
+ ensureTransformationInfo();
+ mTransformationInfo.mAlpha = alpha;
boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
if (subclassHandlesAlpha) {
mPrivateFlags |= ALPHA_SET;
@@ -7278,7 +7322,9 @@
public final void setTop(int top) {
if (top != mTop) {
updateMatrix();
- if (mMatrixIsIdentity) {
+ final boolean matrixIsIdentity = mTransformationInfo == null
+ || mTransformationInfo.mMatrixIsIdentity;
+ if (matrixIsIdentity) {
if (mAttachInfo != null) {
int minTop;
int yLoc;
@@ -7303,10 +7349,10 @@
onSizeChanged(width, mBottom - mTop, width, oldHeight);
- if (!mMatrixIsIdentity) {
+ if (!matrixIsIdentity) {
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
- mMatrixDirty = true;
+ mTransformationInfo.mMatrixDirty = true;
}
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(true);
@@ -7345,7 +7391,9 @@
public final void setBottom(int bottom) {
if (bottom != mBottom) {
updateMatrix();
- if (mMatrixIsIdentity) {
+ final boolean matrixIsIdentity = mTransformationInfo == null
+ || mTransformationInfo.mMatrixIsIdentity;
+ if (matrixIsIdentity) {
if (mAttachInfo != null) {
int maxBottom;
if (bottom < mBottom) {
@@ -7367,10 +7415,10 @@
onSizeChanged(width, mBottom - mTop, width, oldHeight);
- if (!mMatrixIsIdentity) {
+ if (!matrixIsIdentity) {
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
- mMatrixDirty = true;
+ mTransformationInfo.mMatrixDirty = true;
}
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(true);
@@ -7400,7 +7448,9 @@
public final void setLeft(int left) {
if (left != mLeft) {
updateMatrix();
- if (mMatrixIsIdentity) {
+ final boolean matrixIsIdentity = mTransformationInfo == null
+ || mTransformationInfo.mMatrixIsIdentity;
+ if (matrixIsIdentity) {
if (mAttachInfo != null) {
int minLeft;
int xLoc;
@@ -7425,10 +7475,10 @@
onSizeChanged(mRight - mLeft, height, oldWidth, height);
- if (!mMatrixIsIdentity) {
+ if (!matrixIsIdentity) {
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
- mMatrixDirty = true;
+ mTransformationInfo.mMatrixDirty = true;
}
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(true);
@@ -7458,7 +7508,9 @@
public final void setRight(int right) {
if (right != mRight) {
updateMatrix();
- if (mMatrixIsIdentity) {
+ final boolean matrixIsIdentity = mTransformationInfo == null
+ || mTransformationInfo.mMatrixIsIdentity;
+ if (matrixIsIdentity) {
if (mAttachInfo != null) {
int maxRight;
if (right < mRight) {
@@ -7480,10 +7532,10 @@
onSizeChanged(mRight - mLeft, height, oldWidth, height);
- if (!mMatrixIsIdentity) {
+ if (!matrixIsIdentity) {
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
- mMatrixDirty = true;
+ mTransformationInfo.mMatrixDirty = true;
}
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(true);
@@ -7501,7 +7553,7 @@
* @return The visual x position of this view, in pixels.
*/
public float getX() {
- return mLeft + mTranslationX;
+ return mLeft + (mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0);
}
/**
@@ -7523,7 +7575,7 @@
* @return The visual y position of this view, in pixels.
*/
public float getY() {
- return mTop + mTranslationY;
+ return mTop + (mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0);
}
/**
@@ -7546,7 +7598,7 @@
* @return The horizontal position of this view relative to its left position, in pixels.
*/
public float getTranslationX() {
- return mTranslationX;
+ return mTransformationInfo != null ? mTransformationInfo.mTranslationX : 0;
}
/**
@@ -7560,12 +7612,14 @@
* @attr ref android.R.styleable#View_translationX
*/
public void setTranslationX(float translationX) {
- if (mTranslationX != translationX) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mTranslationX != translationX) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mTranslationX = translationX;
- mMatrixDirty = true;
+ info.mTranslationX = translationX;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7580,7 +7634,7 @@
* in pixels.
*/
public float getTranslationY() {
- return mTranslationY;
+ return mTransformationInfo != null ? mTransformationInfo.mTranslationY : 0;
}
/**
@@ -7594,12 +7648,14 @@
* @attr ref android.R.styleable#View_translationY
*/
public void setTranslationY(float translationY) {
- if (mTranslationY != translationY) {
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ if (info.mTranslationY != translationY) {
invalidateParentCaches();
// Double-invalidation is necessary to capture view's old and new areas
invalidate(false);
- mTranslationY = translationY;
- mMatrixDirty = true;
+ info.mTranslationY = translationY;
+ info.mMatrixDirty = true;
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7609,63 +7665,78 @@
* @hide
*/
public void setFastTranslationX(float x) {
- mTranslationX = x;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mTranslationX = x;
+ info.mMatrixDirty = true;
}
/**
* @hide
*/
public void setFastTranslationY(float y) {
- mTranslationY = y;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mTranslationY = y;
+ info.mMatrixDirty = true;
}
/**
* @hide
*/
public void setFastX(float x) {
- mTranslationX = x - mLeft;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mTranslationX = x - mLeft;
+ info.mMatrixDirty = true;
}
/**
* @hide
*/
public void setFastY(float y) {
- mTranslationY = y - mTop;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mTranslationY = y - mTop;
+ info.mMatrixDirty = true;
}
/**
* @hide
*/
public void setFastScaleX(float x) {
- mScaleX = x;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mScaleX = x;
+ info.mMatrixDirty = true;
}
/**
* @hide
*/
public void setFastScaleY(float y) {
- mScaleY = y;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mScaleY = y;
+ info.mMatrixDirty = true;
}
/**
* @hide
*/
public void setFastAlpha(float alpha) {
- mAlpha = alpha;
+ ensureTransformationInfo();
+ mTransformationInfo.mAlpha = alpha;
}
/**
* @hide
*/
public void setFastRotationY(float y) {
- mRotationY = y;
- mMatrixDirty = true;
+ ensureTransformationInfo();
+ final TransformationInfo info = mTransformationInfo;
+ info.mRotationY = y;
+ info.mMatrixDirty = true;
}
/**
@@ -7675,12 +7746,14 @@
*/
public void getHitRect(Rect outRect) {
updateMatrix();
- if (mMatrixIsIdentity || mAttachInfo == null) {
+ final TransformationInfo info = mTransformationInfo;
+ if (info == null || info.mMatrixIsIdentity || mAttachInfo == null) {
outRect.set(mLeft, mTop, mRight, mBottom);
} else {
final RectF tmpRect = mAttachInfo.mTmpTransformRect;
- tmpRect.set(-mPivotX, -mPivotY, getWidth() - mPivotX, getHeight() - mPivotY);
- mMatrix.mapRect(tmpRect);
+ tmpRect.set(-info.mPivotX, -info.mPivotY,
+ getWidth() - info.mPivotX, getHeight() - info.mPivotY);
+ info.mMatrix.mapRect(tmpRect);
outRect.set((int) tmpRect.left + mLeft, (int) tmpRect.top + mTop,
(int) tmpRect.right + mLeft, (int) tmpRect.bottom + mTop);
}
@@ -7768,7 +7841,9 @@
public void offsetTopAndBottom(int offset) {
if (offset != 0) {
updateMatrix();
- if (mMatrixIsIdentity) {
+ final boolean matrixIsIdentity = mTransformationInfo == null
+ || mTransformationInfo.mMatrixIsIdentity;
+ if (matrixIsIdentity) {
final ViewParent p = mParent;
if (p != null && mAttachInfo != null) {
final Rect r = mAttachInfo.mTmpInvalRect;
@@ -7794,7 +7869,7 @@
mTop += offset;
mBottom += offset;
- if (!mMatrixIsIdentity) {
+ if (!matrixIsIdentity) {
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -7810,7 +7885,9 @@
public void offsetLeftAndRight(int offset) {
if (offset != 0) {
updateMatrix();
- if (mMatrixIsIdentity) {
+ final boolean matrixIsIdentity = mTransformationInfo == null
+ || mTransformationInfo.mMatrixIsIdentity;
+ if (matrixIsIdentity) {
final ViewParent p = mParent;
if (p != null && mAttachInfo != null) {
final Rect r = mAttachInfo.mTmpInvalRect;
@@ -7833,7 +7910,7 @@
mLeft += offset;
mRight += offset;
- if (!mMatrixIsIdentity) {
+ if (!matrixIsIdentity) {
mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
invalidate(false);
}
@@ -8309,7 +8386,8 @@
@ViewDebug.ExportedProperty(category = "drawing")
public boolean isOpaque() {
return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK &&
- (mAlpha >= 1.0f - ViewConfiguration.ALPHA_THRESHOLD);
+ ((mTransformationInfo != null ? mTransformationInfo.mAlpha : 1)
+ >= 1.0f - ViewConfiguration.ALPHA_THRESHOLD);
}
/**
@@ -10954,7 +11032,9 @@
if (sizeChanged) {
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
- mMatrixDirty = true;
+ if (mTransformationInfo != null) {
+ mTransformationInfo.mMatrixDirty = true;
+ }
}
onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
}
@@ -11747,14 +11827,22 @@
+ "two integers");
}
- location[0] = mLeft + (int) (mTranslationX + 0.5f);
- location[1] = mTop + (int) (mTranslationY + 0.5f);
+ location[0] = mLeft;
+ location[1] = mTop;
+ if (mTransformationInfo != null) {
+ location[0] += (int) (mTransformationInfo.mTranslationX + 0.5f);
+ location[1] += (int) (mTransformationInfo.mTranslationY + 0.5f);
+ }
ViewParent viewParent = mParent;
while (viewParent instanceof View) {
final View view = (View)viewParent;
- location[0] += view.mLeft + (int) (view.mTranslationX + 0.5f) - view.mScrollX;
- location[1] += view.mTop + (int) (view.mTranslationY + 0.5f) - view.mScrollY;
+ location[0] += view.mLeft - view.mScrollX;
+ location[1] += view.mTop - view.mScrollY;
+ if (view.mTransformationInfo != null) {
+ location[0] += (int) (view.mTransformationInfo.mTranslationX + 0.5f);
+ location[1] += (int) (view.mTransformationInfo.mTranslationY + 0.5f);
+ }
viewParent = view.mParent;
}
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 6ed49ee..84dc7d8 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -51,7 +51,7 @@
* The View whose properties are being animated by this class. This is set at
* construction time.
*/
- private View mView;
+ private final View mView;
/**
* The duration of the underlying Animator object. By default, we don't set the duration
@@ -225,6 +225,7 @@
*/
ViewPropertyAnimator(View view) {
mView = view;
+ view.ensureTransformationInfo();
}
/**
@@ -721,36 +722,37 @@
* @param value The value to set the property to
*/
private void setValue(int propertyConstant, float value) {
+ final View.TransformationInfo info = mView.mTransformationInfo;
switch (propertyConstant) {
case TRANSLATION_X:
- mView.mTranslationX = value;
+ info.mTranslationX = value;
break;
case TRANSLATION_Y:
- mView.mTranslationY = value;
+ info.mTranslationY = value;
break;
case ROTATION:
- mView.mRotation = value;
+ info.mRotation = value;
break;
case ROTATION_X:
- mView.mRotationX = value;
+ info.mRotationX = value;
break;
case ROTATION_Y:
- mView.mRotationY = value;
+ info.mRotationY = value;
break;
case SCALE_X:
- mView.mScaleX = value;
+ info.mScaleX = value;
break;
case SCALE_Y:
- mView.mScaleY = value;
+ info.mScaleY = value;
break;
case X:
- mView.mTranslationX = value - mView.mLeft;
+ info.mTranslationX = value - mView.mLeft;
break;
case Y:
- mView.mTranslationY = value - mView.mTop;
+ info.mTranslationY = value - mView.mTop;
break;
case ALPHA:
- mView.mAlpha = value;
+ info.mAlpha = value;
break;
}
}
@@ -762,27 +764,28 @@
* @return float The value of the named property
*/
private float getValue(int propertyConstant) {
+ final View.TransformationInfo info = mView.mTransformationInfo;
switch (propertyConstant) {
case TRANSLATION_X:
- return mView.mTranslationX;
+ return info.mTranslationX;
case TRANSLATION_Y:
- return mView.mTranslationY;
+ return info.mTranslationY;
case ROTATION:
- return mView.mRotation;
+ return info.mRotation;
case ROTATION_X:
- return mView.mRotationX;
+ return info.mRotationX;
case ROTATION_Y:
- return mView.mRotationY;
+ return info.mRotationY;
case SCALE_X:
- return mView.mScaleX;
+ return info.mScaleX;
case SCALE_Y:
- return mView.mScaleY;
+ return info.mScaleY;
case X:
- return mView.mLeft + mView.mTranslationX;
+ return mView.mLeft + info.mTranslationX;
case Y:
- return mView.mTop + mView.mTranslationY;
+ return mView.mTop + info.mTranslationY;
case ALPHA:
- return mView.mAlpha;
+ return info.mAlpha;
}
return 0;
}
@@ -861,7 +864,7 @@
}
}
if ((propertyMask & TRANSFORM_MASK) != 0) {
- mView.mMatrixDirty = true;
+ mView.mTransformationInfo.mMatrixDirty = true;
mView.mPrivateFlags |= View.DRAWN; // force another invalidation
}
// invalidate(false) in all cases except if alphaHandled gets set to true
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 96c1512..17a516c 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -177,7 +177,14 @@
@ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR, to = "TYPE_SYSTEM_ERROR"),
@ViewDebug.IntToString(from = TYPE_INPUT_METHOD, to = "TYPE_INPUT_METHOD"),
@ViewDebug.IntToString(from = TYPE_INPUT_METHOD_DIALOG, to = "TYPE_INPUT_METHOD_DIALOG"),
+ @ViewDebug.IntToString(from = TYPE_WALLPAPER, to = "TYPE_WALLPAPER"),
+ @ViewDebug.IntToString(from = TYPE_STATUS_BAR_PANEL, to = "TYPE_STATUS_BAR_PANEL"),
@ViewDebug.IntToString(from = TYPE_SECURE_SYSTEM_OVERLAY, to = "TYPE_SECURE_SYSTEM_OVERLAY"),
+ @ViewDebug.IntToString(from = TYPE_DRAG, to = "TYPE_DRAG"),
+ @ViewDebug.IntToString(from = TYPE_STATUS_BAR_SUB_PANEL, to = "TYPE_STATUS_BAR_SUB_PANEL"),
+ @ViewDebug.IntToString(from = TYPE_POINTER, to = "TYPE_POINTER"),
+ @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR, to = "TYPE_NAVIGATION_BAR"),
+ @ViewDebug.IntToString(from = TYPE_VOLUME_OVERLAY, to = "TYPE_VOLUME_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS")
})
public int type;
diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java
index 9fea506..bc44521 100644
--- a/core/java/android/widget/ActivityChooserModel.java
+++ b/core/java/android/widget/ActivityChooserModel.java
@@ -663,6 +663,17 @@
}
}
+ /**
+ * Gets the history size.
+ *
+ * @return The history size.
+ */
+ public int getHistorySize() {
+ synchronized (mInstanceLock) {
+ return mHistoricalRecords.size();
+ }
+ }
+
@Override
protected void finalize() throws Throwable {
super.finalize();
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index fcc7938..312303d 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -28,6 +28,7 @@
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
@@ -76,6 +77,11 @@
private final LinearLayout mActivityChooserContent;
/**
+ * Stores the background drawable to allow hiding and latter showing.
+ */
+ private final Drawable mActivityChooserContentBackground;
+
+ /**
* The expand activities action button;
*/
private final FrameLayout mExpandActivityOverflowButton;
@@ -194,12 +200,15 @@
Drawable expandActivityOverflowButtonDrawable = attributesArray.getDrawable(
R.styleable.ActivityChooserView_expandActivityOverflowButtonDrawable);
+ attributesArray.recycle();
+
LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(R.layout.activity_chooser_view, this, true);
mCallbacks = new Callbacks();
mActivityChooserContent = (LinearLayout) findViewById(R.id.activity_chooser_view_content);
+ mActivityChooserContentBackground = mActivityChooserContent.getBackground();
mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
mDefaultActivityButton.setOnClickListener(mCallbacks);
@@ -217,7 +226,7 @@
@Override
public void onChanged() {
super.onChanged();
- updateButtons();
+ updateAppearance();
}
});
@@ -352,9 +361,16 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- mActivityChooserContent.measure(widthMeasureSpec, heightMeasureSpec);
- setMeasuredDimension(mActivityChooserContent.getMeasuredWidth(),
- mActivityChooserContent.getMeasuredHeight());
+ View child = mActivityChooserContent;
+ // If the default action is not visible we want to be as tall as the
+ // ActionBar so if this widget is used in the latter it will look as
+ // a normal action button.
+ if (mDefaultActivityButton.getVisibility() != VISIBLE) {
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
+ MeasureSpec.EXACTLY);
+ }
+ measureChild(child, widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(child.getMeasuredWidth(), child.getMeasuredHeight());
}
@Override
@@ -367,11 +383,6 @@
}
}
- @Override
- protected void onDraw(Canvas canvas) {
- mActivityChooserContent.onDraw(canvas);
- }
-
public ActivityChooserModel getDataModel() {
return mAdapter.getDataModel();
}
@@ -417,21 +428,29 @@
/**
* Updates the buttons state.
*/
- private void updateButtons() {
+ private void updateAppearance() {
+ // Expand overflow button.
+ if (mAdapter.getCount() > 0) {
+ mExpandActivityOverflowButton.setEnabled(true);
+ } else {
+ mExpandActivityOverflowButton.setEnabled(false);
+ }
+ // Default activity button.
final int activityCount = mAdapter.getActivityCount();
- if (activityCount > 0) {
+ final int historySize = mAdapter.getHistorySize();
+ if (activityCount > 0 && historySize > 0) {
mDefaultActivityButton.setVisibility(VISIBLE);
- if (mAdapter.getCount() > 0) {
- mExpandActivityOverflowButton.setEnabled(true);
- } else {
- mExpandActivityOverflowButton.setEnabled(false);
- }
ResolveInfo activity = mAdapter.getDefaultActivity();
PackageManager packageManager = mContext.getPackageManager();
mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager));
} else {
- mDefaultActivityButton.setVisibility(View.INVISIBLE);
- mExpandActivityOverflowButton.setEnabled(false);
+ mDefaultActivityButton.setVisibility(View.GONE);
+ }
+ // Activity chooser content.
+ if (mDefaultActivityButton.getVisibility() == VISIBLE) {
+ mActivityChooserContent.setBackgroundDrawable(mActivityChooserContentBackground);
+ } else {
+ mActivityChooserContent.setBackgroundDrawable(null);
}
}
@@ -678,6 +697,10 @@
return mDataModel.getActivityCount();
}
+ public int getHistorySize() {
+ return mDataModel.getHistorySize();
+ }
+
public int getMaxActivityCount() {
return mMaxActivityCount;
}
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 3b67f44..5077be6 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -31,6 +31,7 @@
import android.view.LayoutInflater;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.EditorInfo;
import android.widget.NumberPicker.OnValueChangeListener;
import com.android.internal.R;
@@ -81,10 +82,10 @@
private static final boolean DEFAULT_ENABLED_STATE = true;
- private final NumberPicker mDaySpinner;
-
private final LinearLayout mSpinners;
+ private final NumberPicker mDaySpinner;
+
private final NumberPicker mMonthSpinner;
private final NumberPicker mYearSpinner;
@@ -481,16 +482,20 @@
private void reorderSpinners() {
mSpinners.removeAllViews();
char[] order = DateFormat.getDateFormatOrder(getContext());
- for (int i = 0; i < order.length; i++) {
+ final int spinnerCount = order.length;
+ for (int i = 0; i < spinnerCount; i++) {
switch (order[i]) {
case DateFormat.DATE:
mSpinners.addView(mDaySpinner);
+ setImeOptions(mDaySpinner, spinnerCount, i);
break;
case DateFormat.MONTH:
mSpinners.addView(mMonthSpinner);
+ setImeOptions(mMonthSpinner, spinnerCount, i);
break;
case DateFormat.YEAR:
mSpinners.addView(mYearSpinner);
+ setImeOptions(mYearSpinner, spinnerCount, i);
break;
default:
throw new IllegalArgumentException();
@@ -669,6 +674,42 @@
}
/**
+ * Sets the IME options for a spinner based on its ordering.
+ *
+ * @param spinner The spinner.
+ * @param spinnerCount The total spinner count.
+ * @param spinnerIndex The index of the given spinner.
+ */
+ private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
+ final int imeOptions;
+ if (spinnerIndex < spinnerCount - 1) {
+ imeOptions = EditorInfo.IME_ACTION_NEXT;
+ } else {
+ imeOptions = EditorInfo.IME_ACTION_DONE;
+ }
+ TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
+ input.setImeOptions(imeOptions);
+ }
+
+ private void setContentDescriptions() {
+ // Day
+ String text = mContext.getString(R.string.date_picker_increment_day_button);
+ mDaySpinner.findViewById(R.id.increment).setContentDescription(text);
+ text = mContext.getString(R.string.date_picker_decrement_day_button);
+ mDaySpinner.findViewById(R.id.decrement).setContentDescription(text);
+ // Month
+ text = mContext.getString(R.string.date_picker_increment_month_button);
+ mMonthSpinner.findViewById(R.id.increment).setContentDescription(text);
+ text = mContext.getString(R.string.date_picker_decrement_month_button);
+ mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ // Year
+ text = mContext.getString(R.string.date_picker_increment_year_button);
+ mYearSpinner.findViewById(R.id.increment).setContentDescription(text);
+ text = mContext.getString(R.string.date_picker_decrement_year_button);
+ mYearSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ }
+
+ /**
* Class for managing state storing/restoring.
*/
private static class SavedState extends BaseSavedState {
@@ -720,22 +761,4 @@
}
};
}
-
- private void setContentDescriptions() {
- // Day
- String text = mContext.getString(R.string.date_picker_increment_day_button);
- mDaySpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.date_picker_decrement_day_button);
- mDaySpinner.findViewById(R.id.decrement).setContentDescription(text);
- // Month
- text = mContext.getString(R.string.date_picker_increment_month_button);
- mMonthSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.date_picker_decrement_month_button);
- mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text);
- // Year
- text = mContext.getString(R.string.date_picker_increment_year_button);
- mYearSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.date_picker_decrement_year_button);
- mYearSpinner.findViewById(R.id.decrement).setContentDescription(text);
- }
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 35e48f2..5345fa4 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -33,7 +33,6 @@
import android.graphics.Rect;
import android.graphics.Paint.Align;
import android.graphics.drawable.Drawable;
-import android.os.SystemClock;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
@@ -517,7 +516,10 @@
mInputText = (EditText) findViewById(R.id.numberpicker_input);
mInputText.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
- if (!hasFocus) {
+ if (hasFocus) {
+ mInputText.selectAll();
+ } else {
+ mInputText.setSelection(0, 0);
validateInputTextView(v);
}
}
@@ -687,7 +689,6 @@
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mInputText, 0);
- mInputText.setSelection(0, mInputText.getText().length());
return true;
}
VelocityTracker velocityTracker = mVelocityTracker;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ebe22cc..b948114 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3726,19 +3726,19 @@
// instead turning this into the normal enter key codes that an
// app may be expecting.
if (actionCode == EditorInfo.IME_ACTION_NEXT) {
- View v = focusSearch(FOCUS_DOWN);
+ View v = focusSearch(FOCUS_FORWARD);
if (v != null) {
- if (!v.requestFocus(FOCUS_DOWN)) {
+ if (!v.requestFocus(FOCUS_FORWARD)) {
throw new IllegalStateException("focus search returned a view " +
"that wasn't able to take focus!");
}
}
return;
-
+
} else if (actionCode == EditorInfo.IME_ACTION_PREVIOUS) {
- View v = focusSearch(FOCUS_UP);
+ View v = focusSearch(FOCUS_BACKWARD);
if (v != null) {
- if (!v.requestFocus(FOCUS_UP)) {
+ if (!v.requestFocus(FOCUS_BACKWARD)) {
throw new IllegalStateException("focus search returned a view " +
"that wasn't able to take focus!");
}
@@ -3750,10 +3750,11 @@
if (imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
+ clearFocus();
return;
}
}
-
+
Handler h = getHandler();
if (h != null) {
long eventTime = SystemClock.uptimeMillis();
@@ -9558,8 +9559,8 @@
TextView.this.getPositionListener().removeSubscriber(SuggestionsPopupWindow.this);
- if ((mText instanceof Editable) && mSuggestionRangeSpan != null) {
- ((Editable) mText).removeSpan(mSuggestionRangeSpan);
+ if ((mText instanceof Spannable)) {
+ ((Spannable) mText).removeSpan(mSuggestionRangeSpan);
}
setCursorVisible(mCursorWasVisibleBeforeSuggestions);
@@ -9743,7 +9744,7 @@
}
private boolean updateSuggestions() {
- Spannable spannable = (Spannable)TextView.this.mText;
+ Spannable spannable = (Spannable) TextView.this.mText;
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
final int nbSpans = suggestionSpans.length;
@@ -9753,6 +9754,7 @@
int spanUnionEnd = 0;
SuggestionSpan misspelledSpan = null;
+ int underlineColor = 0;
for (int spanIndex = 0; spanIndex < nbSpans; spanIndex++) {
SuggestionSpan suggestionSpan = suggestionSpans[spanIndex];
@@ -9765,6 +9767,9 @@
misspelledSpan = suggestionSpan;
}
+ // The first span dictates the background color of the highlighted text
+ if (spanIndex == 0) underlineColor = suggestionSpan.getUnderlineColor();
+
String[] suggestions = suggestionSpan.getSuggestions();
int nbSuggestions = suggestions.length;
for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
@@ -9807,9 +9812,17 @@
if (mNumberOfSuggestions == 0) return false;
- if (mSuggestionRangeSpan == null) mSuggestionRangeSpan =
- new SuggestionRangeSpan(mHighlightColor);
- ((Editable) mText).setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
+ if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
+ if (underlineColor == 0) {
+ // Fallback on the default highlight color when the first span does not provide one
+ mSuggestionRangeSpan.setBackgroundColor(mHighlightColor);
+ } else {
+ final float BACKGROUND_TRANSPARENCY = 0.3f;
+ final int newAlpha = (int) (Color.alpha(underlineColor) * BACKGROUND_TRANSPARENCY);
+ mSuggestionRangeSpan.setBackgroundColor(
+ (underlineColor & 0x00FFFFFF) + (newAlpha << 24));
+ }
+ spannable.setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mSuggestionsAdapter.notifyDataSetChanged();
@@ -9901,6 +9914,9 @@
suggestionSpansFlags[i]);
}
}
+
+ // Move cursor at the end of the replacement word
+ Selection.setSelection(editable, spanEnd + lengthDifference);
}
}
hide();
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 2350229..7865d50 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -16,8 +16,6 @@
package android.widget;
-import com.android.internal.R;
-
import android.annotation.Widget;
import android.content.Context;
import android.content.res.Configuration;
@@ -30,8 +28,11 @@
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.EditorInfo;
import android.widget.NumberPicker.OnValueChangeListener;
+import com.android.internal.R;
+
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Locale;
@@ -149,6 +150,8 @@
onTimeChanged();
}
});
+ EditText hourInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
+ hourInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
// divider (only for the new widget style)
mDivider = (TextView) findViewById(R.id.divider);
@@ -184,6 +187,8 @@
onTimeChanged();
}
});
+ EditText minuteInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
+ minuteInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
/* Get the localized am/pm strings and use them in the spinner */
mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
@@ -214,6 +219,8 @@
}
});
}
+ EditText amPmInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
+ amPmInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
// update controls to initial state
updateHourControl();
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index 2f5fd5a..1f4da3a 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -202,6 +202,13 @@
#define INPUT_OPERATION_GENERIC_FAILURE 5003
#define INPUT_OPERATION_SUCCESS 5004
+#define HEALTH_OPERATION_SUCCESS 6000
+#define HEALTH_OPERATION_ERROR 6001
+#define HEALTH_OPERATION_INVALID_ARGS 6002
+#define HEALTH_OPERATION_GENERIC_FAILURE 6003
+#define HEALTH_OPERATION_NOT_FOUND 6004
+#define HEALTH_OPERATION_NOT_ALLOWED 6005
+
#endif
} /* namespace android */
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index eee256a..0335ce7 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -74,6 +74,7 @@
static jmethodID method_onPanDeviceConnectionResult;
static jmethodID method_onHealthDevicePropertyChanged;
static jmethodID method_onHealthDeviceChannelChanged;
+static jmethodID method_onHealthDeviceConnectionResult;
typedef event_loop_native_data_t native_data_t;
@@ -141,6 +142,9 @@
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
"(Ljava/lang/String;I)V");
+ method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
+ "onHealthDeviceConnectionResult",
+ "(II)V");
method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
@@ -1533,6 +1537,39 @@
free(user);
}
+void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
+ LOGV("%s", __FUNCTION__);
+
+ native_data_t *nat = (native_data_t *)n;
+ DBusError err;
+ dbus_error_init(&err);
+ JNIEnv *env;
+ nat->vm->GetEnv((void**)&env, nat->envVer);
+
+ jint result = HEALTH_OPERATION_SUCCESS;
+ if (dbus_set_error_from_message(&err, msg)) {
+ if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
+ result = HEALTH_OPERATION_INVALID_ARGS;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
+ result = HEALTH_OPERATION_ERROR;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
+ result = HEALTH_OPERATION_NOT_FOUND;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
+ result = HEALTH_OPERATION_NOT_ALLOWED;
+ } else {
+ result = HEALTH_OPERATION_GENERIC_FAILURE;
+ }
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ }
+
+ LOGV("... Health Device Code = %d, result = %d", code, result);
+ jint code = *(int *) user;
+ env->CallVoidMethod(nat->me,
+ method_onHealthDeviceConnectionResult,
+ code,
+ result);
+ free(user);
+}
#endif
static JNINativeMethod sMethods[] = {
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 292047b..a49c918 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -78,8 +78,8 @@
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-void onConnectPanResult(DBusMessage *msg, void *user, void *n);
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
+void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
@@ -1450,79 +1450,70 @@
}
static jboolean createChannelNative(JNIEnv *env, jobject object,
- jstring devicePath, jstring appPath, jstring config) {
+ jstring devicePath, jstring appPath, jstring config,
+ jint code) {
LOGV("%s", __FUNCTION__);
- jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
+ jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+ struct event_loop_native_data_t *eventLoopNat =
+ get_EventLoop_native_data(env, eventLoop);
- if (nat) {
- DBusError err;
- dbus_error_init(&err);
-
+ if (nat && eventLoopNat) {
const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
const char *c_config = env->GetStringUTFChars(config, NULL);
+ int *data = (int *) malloc(sizeof(int));
+ if (data == NULL) return JNI_FALSE;
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- c_device_path,
- DBUS_HEALTH_DEVICE_IFACE,
- "CreateChannel",
- DBUS_TYPE_OBJECT_PATH, &c_app_path,
- DBUS_TYPE_STRING, &c_config,
- DBUS_TYPE_INVALID);
+ *data = code;
+ bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
+ data, eventLoopNat, c_device_path,
+ DBUS_HEALTH_DEVICE_IFACE, "CreateChannel",
+ DBUS_TYPE_OBJECT_PATH, &c_app_path,
+ DBUS_TYPE_STRING, &c_config,
+ DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(devicePath, c_device_path);
env->ReleaseStringUTFChars(appPath, c_app_path);
env->ReleaseStringUTFChars(config, c_config);
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- result = JNI_TRUE;
- }
+ return ret ? JNI_TRUE : JNI_FALSE;
}
#endif
- return result;
+ return JNI_FALSE;
}
static jboolean destroyChannelNative(JNIEnv *env, jobject object, jstring devicePath,
- jstring channelPath) {
+ jstring channelPath, jint code) {
LOGE("%s", __FUNCTION__);
- jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
+ jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+ struct event_loop_native_data_t *eventLoopNat =
+ get_EventLoop_native_data(env, eventLoop);
- if (nat) {
- DBusError err;
- dbus_error_init(&err);
-
+ if (nat && eventLoopNat) {
const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
+ int *data = (int *) malloc(sizeof(int));
+ if (data == NULL) return JNI_FALSE;
- DBusMessage *reply = dbus_func_args(env, nat->conn,
- c_device_path,
- DBUS_HEALTH_DEVICE_IFACE,
- "DestroyChannel",
- DBUS_TYPE_OBJECT_PATH, &c_channel_path,
- DBUS_TYPE_INVALID);
+ *data = code;
+ bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
+ data, eventLoopNat, c_device_path,
+ DBUS_HEALTH_DEVICE_IFACE, "DestroyChannel",
+ DBUS_TYPE_OBJECT_PATH, &c_channel_path,
+ DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(devicePath, c_device_path);
env->ReleaseStringUTFChars(channelPath, c_channel_path);
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- }
- } else {
- result = JNI_TRUE;
- }
+ return ret ? JNI_TRUE : JNI_FALSE;
}
#endif
- return result;
+ return JNI_FALSE;
}
static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring devicePath) {
@@ -1755,9 +1746,10 @@
{"unregisterHealthApplicationNative", "(Ljava/lang/String;)Z",
(void *)unregisterHealthApplicationNative},
- {"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
+ {"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Z",
(void *)createChannelNative},
- {"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)destroyChannelNative},
+ {"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
+ (void *)destroyChannelNative},
{"getMainChannelNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getMainChannelNative},
{"getChannelApplicationNative", "(Ljava/lang/String;)Ljava/lang/String;",
(void *)getChannelApplicationNative},
diff --git a/core/res/res/drawable-hdpi/ab_share_pack_holo_dark.9.png b/core/res/res/drawable-hdpi/ab_share_pack_holo_dark.9.png
new file mode 100644
index 0000000..6c14157
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_share_pack_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_share_pack_holo_light.9.png b/core/res/res/drawable-hdpi/ab_share_pack_holo_light.9.png
new file mode 100644
index 0000000..f4ff16b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_share_pack_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_cab_done_default_holo_dark.9.png
index 0d165bb..b0dc31f 100644
--- a/core/res/res/drawable-hdpi/btn_cab_done_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_cab_done_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-hdpi/btn_cab_done_default_holo_light.9.png
index 73c7e25..4bc2683 100644
--- a/core/res/res/drawable-hdpi/btn_cab_done_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_cab_done_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_dark.9.png
index 1459eee..4af38fb 100644
--- a/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_light.9.png
index 04de530..d32f74c 100644
--- a/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_cab_done_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_dark.9.png
index bab70fa..66adffe 100644
--- a/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_light.9.png
index b46adfa..caeff9c 100644
--- a/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_cab_done_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
index db011be..6f747c8 100644
--- a/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
+++ b/core/res/res/drawable-hdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
index d9a9a73..682b2fd 100644
--- a/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_divider_holo_dark.9.png b/core/res/res/drawable-hdpi/list_divider_holo_dark.9.png
new file mode 100644
index 0000000..986ab0b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_divider_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_divider_holo_light.9.png b/core/res/res/drawable-hdpi/list_divider_holo_light.9.png
new file mode 100644
index 0000000..0279e17
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_divider_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_share_pack_holo_dark.9.png b/core/res/res/drawable-mdpi/ab_share_pack_holo_dark.9.png
new file mode 100644
index 0000000..ed4ba34
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_share_pack_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png b/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png
new file mode 100644
index 0000000..1983c68
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_share_pack_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_cab_done_default_holo_dark.9.png
index 9e936b3..5461b9c 100644
--- a/core/res/res/drawable-mdpi/btn_cab_done_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_cab_done_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-mdpi/btn_cab_done_default_holo_light.9.png
index 0360104..5dc6f80 100644
--- a/core/res/res/drawable-mdpi/btn_cab_done_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_cab_done_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_dark.9.png
index dd947d2..a70b53c 100644
--- a/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_light.9.png
index 51cfca2..c7a9896 100644
--- a/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_cab_done_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_dark.9.png
index fd6e6c7..85d7aad 100644
--- a/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_light.9.png
index 5db212c..f7b01e0 100644
--- a/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_cab_done_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
index 306cac8..6bf21e3 100644
--- a/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
+++ b/core/res/res/drawable-mdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
index cc081ad..70fe31a 100644
--- a/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_divider_holo_dark.9.png b/core/res/res/drawable-mdpi/list_divider_holo_dark.9.png
new file mode 100644
index 0000000..986ab0b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_divider_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_divider_holo_light.9.png b/core/res/res/drawable-mdpi/list_divider_holo_light.9.png
new file mode 100644
index 0000000..0279e17
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_divider_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/list_divider_holo_dark.9.png b/core/res/res/drawable-nodpi/list_divider_holo_dark.9.png
deleted file mode 100644
index 2e7951f..0000000
--- a/core/res/res/drawable-nodpi/list_divider_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/list_divider_holo_light.9.png b/core/res/res/drawable-nodpi/list_divider_holo_light.9.png
deleted file mode 100644
index 17d8a54..0000000
--- a/core/res/res/drawable-nodpi/list_divider_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_share_pack_holo_dark.9.png b/core/res/res/drawable-xhdpi/ab_share_pack_holo_dark.9.png
new file mode 100644
index 0000000..55099d49
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_share_pack_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_share_pack_holo_light.9.png b/core/res/res/drawable-xhdpi/ab_share_pack_holo_light.9.png
new file mode 100644
index 0000000..3c4701f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_share_pack_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_dark.9.png
index 01efef4..7ef2db7 100644
--- a/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_light.9.png
index c287605..2283b4c 100644
--- a/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_cab_done_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_dark.9.png
index 9a496e8..6d2039e 100644
--- a/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_light.9.png
index e2a38b4..3c909b5 100644
--- a/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_cab_done_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_dark.9.png
index 911722f..131d103 100644
--- a/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_light.9.png
index da169bf..3e7dcdf 100644
--- a/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_cab_done_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png
index af72732..45a0f1d 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png
index 79c162f..528e554 100644
--- a/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_divider_holo_dark.9.png b/core/res/res/drawable-xhdpi/list_divider_holo_dark.9.png
new file mode 100644
index 0000000..e62f011
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/list_divider_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_divider_holo_light.9.png b/core/res/res/drawable-xhdpi/list_divider_holo_light.9.png
new file mode 100644
index 0000000..65061c0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/list_divider_holo_light.9.png
Binary files differ
diff --git a/core/res/res/layout/activity_chooser_view.xml b/core/res/res/layout/activity_chooser_view.xml
index 82e1f83..4057441 100644
--- a/core/res/res/layout/activity_chooser_view.xml
+++ b/core/res/res/layout/activity_chooser_view.xml
@@ -19,33 +19,9 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_chooser_view_content"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_gravity="center"
- android:gravity="center"
- style="?android:attr/actionButtonStyle"
- android:padding="0dip">
-
- <FrameLayout
- android:id="@+id/default_activity_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:focusable="true"
- android:addStatesFromChildren="true"
- android:background="?android:attr/actionBarItemBackground">
-
- <ImageView android:id="@+id/image"
- android:layout_width="32dip"
- android:layout_height="32dip"
- android:layout_gravity="center"
- android:layout_marginTop="4dip"
- android:layout_marginBottom="4dip"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:scaleType="fitCenter"
- android:adjustViewBounds="true" />
-
- </FrameLayout>
+ style="?android:attr/activityChooserViewStyle">
<FrameLayout
android:id="@+id/expand_activities_button"
@@ -60,10 +36,32 @@
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_gravity="center"
- android:layout_marginTop="4dip"
- android:layout_marginBottom="4dip"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
+ android:layout_marginTop="2dip"
+ android:layout_marginBottom="2dip"
+ android:layout_marginLeft="12dip"
+ android:layout_marginRight="12dip"
+ android:scaleType="fitCenter"
+ android:adjustViewBounds="true" />
+
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/default_activity_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:focusable="true"
+ android:addStatesFromChildren="true"
+ android:background="?android:attr/actionBarItemBackground">
+
+ <ImageView android:id="@+id/image"
+ android:layout_width="32dip"
+ android:layout_height="32dip"
+ android:layout_gravity="center"
+ android:layout_marginTop="2dip"
+ android:layout_marginBottom="2dip"
+ android:layout_marginLeft="12dip"
+ android:layout_marginRight="12dip"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
diff --git a/core/res/res/layout/activity_list_item.xml b/core/res/res/layout/activity_list_item.xml
index 7022fe1..572caf0 100644
--- a/core/res/res/layout/activity_list_item.xml
+++ b/core/res/res/layout/activity_list_item.xml
@@ -33,6 +33,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:paddingLeft="6dip" />
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" />
</LinearLayout>
diff --git a/core/res/res/layout/activity_list_item_2.xml b/core/res/res/layout/activity_list_item_2.xml
index 3b84c733..a58ebfc 100644
--- a/core/res/res/layout/activity_list_item_2.xml
+++ b/core/res/res/layout/activity_list_item_2.xml
@@ -18,7 +18,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:drawablePadding="14dip"
android:paddingLeft="16dip"
diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml
index 66e3b8a..c0404be 100644
--- a/core/res/res/layout/resolve_list_item.xml
+++ b/core/res/res/layout/resolve_list_item.xml
@@ -23,8 +23,8 @@
android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:paddingLeft="10dip"
- android:paddingRight="15dip">
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip">
<!-- Activity icon when presenting dialog -->
<ImageView android:id="@+id/icon"
@@ -39,18 +39,18 @@
android:layout_height="wrap_content" >
<!-- Activity name -->
<TextView android:id="@android:id/text1"
- android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
- android:paddingLeft="10dip" />
+ android:paddingLeft="16dip" />
<!-- Extended activity info to distinguish between duplicate activity names -->
<TextView android:id="@android:id/text2"
- android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
- android:paddingLeft="10dip" />
+ android:paddingLeft="16dip" />
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/simple_list_item_1.xml b/core/res/res/layout/simple_list_item_1.xml
index 252e006..c5e3efc 100644
--- a/core/res/res/layout/simple_list_item_1.xml
+++ b/core/res/res/layout/simple_list_item_1.xml
@@ -18,9 +18,9 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:minHeight="?android:attr/listPreferredItemHeight"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>
diff --git a/core/res/res/layout/simple_list_item_2.xml b/core/res/res/layout/simple_list_item_2.xml
index 9b6c62a..9369876 100644
--- a/core/res/res/layout/simple_list_item_2.xml
+++ b/core/res/res/layout/simple_list_item_2.xml
@@ -24,8 +24,8 @@
<TextView android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginLeft="8dip"
- android:layout_marginTop="8dip"
+ android:layout_marginLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:layout_marginTop="8dip"
android:textAppearance="?android:attr/textAppearanceListItem"
/>
@@ -33,7 +33,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@android:id/text1"
- android:layout_alignLeft="@android:id/text1"
+ android:layout_alignLeft="@android:id/text1"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
diff --git a/core/res/res/layout/simple_list_item_activated_1.xml b/core/res/res/layout/simple_list_item_activated_1.xml
index d60f93b..a5fb5d1 100644
--- a/core/res/res/layout/simple_list_item_activated_1.xml
+++ b/core/res/res/layout/simple_list_item_activated_1.xml
@@ -18,8 +18,10 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceListItem"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:background="?android:attr/activatedBackgroundIndicator"
- android:minHeight="?android:attr/listPreferredItemHeight"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>
diff --git a/core/res/res/layout/simple_list_item_activated_2.xml b/core/res/res/layout/simple_list_item_activated_2.xml
index 5be5c92..8746f6f 100644
--- a/core/res/res/layout/simple_list_item_activated_2.xml
+++ b/core/res/res/layout/simple_list_item_activated_2.xml
@@ -27,9 +27,9 @@
<TextView android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginLeft="8dip"
- android:layout_marginTop="8dip"
- android:textAppearance="?android:attr/textAppearanceLarge"
+ android:layout_marginLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:layout_marginTop="6dip"
+ android:textAppearance="?android:attr/textAppearanceListItem"
/>
<TextView android:id="@android:id/text2"
diff --git a/core/res/res/layout/simple_list_item_checked.xml b/core/res/res/layout/simple_list_item_checked.xml
index 79d3a18..c9153f8 100644
--- a/core/res/res/layout/simple_list_item_checked.xml
+++ b/core/res/res/layout/simple_list_item_checked.xml
@@ -17,10 +17,10 @@
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:textAppearance="?android:attr/textAppearanceListItem"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:checkMark="?android:attr/textCheckMark"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
/>
diff --git a/core/res/res/layout/simple_list_item_single_choice.xml b/core/res/res/layout/simple_list_item_single_choice.xml
index ac4a4a8..4a6cefa 100644
--- a/core/res/res/layout/simple_list_item_single_choice.xml
+++ b/core/res/res/layout/simple_list_item_single_choice.xml
@@ -17,10 +17,10 @@
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:textAppearance="?android:attr/textAppearanceListItem"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
/>
diff --git a/core/res/res/layout/simple_spinner_item.xml b/core/res/res/layout/simple_spinner_item.xml
index 77929ee..61dc025 100644
--- a/core/res/res/layout/simple_spinner_item.xml
+++ b/core/res/res/layout/simple_spinner_item.xml
@@ -19,7 +19,7 @@
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
- style="?android:attr/spinnerItemStyle"
+ style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 0bf5b0a..525b03a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -235,6 +235,11 @@
<!-- The list item height for search results. @hide -->
<attr name="searchResultListItemHeight" format="dimension" />
+ <!-- The preferred padding along the left edge of list items. -->
+ <attr name="listPreferredItemPaddingLeft" format="dimension" />
+ <!-- The preferred padding along the right edge of list items. -->
+ <attr name="listPreferredItemPaddingRight" format="dimension" />
+
<!-- The preferred TextAppearance for the primary text of list items. -->
<attr name="textAppearanceListItem" format="reference" />
<!-- The preferred TextAppearance for the primary text of small list items. -->
@@ -597,6 +602,9 @@
<!-- The DatePicker style. -->
<attr name="datePickerStyle" format="reference" />
+ <!-- Default ActivityChooserView style. -->
+ <attr name="activityChooserViewStyle" format="reference" />
+
<!-- Fast scroller styles -->
<eat-comment />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bc2b907..50dee12 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1798,6 +1798,14 @@
<public type="attr" name="textAppearanceListItem" />
<public type="attr" name="textAppearanceListItemSmall" />
+ <public type="attr" name="targetDescriptions" />
+ <public type="attr" name="directionDescriptions" />
+
+ <public type="attr" name="overridesImplicitlyEnabledSubtype" />
+
+ <public type="attr" name="listPreferredItemPaddingLeft" />
+ <public type="attr" name="listPreferredItemPaddingRight" />
+
<public type="style" name="TextAppearance.SuggestionHighlight" />
<public type="style" name="Theme.Holo.Light.DarkActionBar" />
@@ -2007,8 +2015,4 @@
<public type="color" name="holo_purple" />
<public type="color" name="holo_blue_bright" />
- <public type="attr" name="targetDescriptions" />
- <public type="attr" name="directionDescriptions" />
-
- <public type="attr" name="overridesImplicitlyEnabledSubtype" />
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 1a6a523..5033611 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -890,6 +890,14 @@
<item name="android:textSize">30sp</item>
</style>
+ <style name="Widget.ActivityChooserView">
+ <item name="android:gravity">center</item>
+ <item name="android:background">@android:drawable/ab_share_pack_holo_dark</item>
+ <item name="android:divider">?android:attr/dividerVertical</item>
+ <item name="android:showDividers">middle</item>
+ <item name="android:dividerPadding">6dip</item>
+ </style>
+
<style name="TextAppearance.SuggestionHighlight">
<item name="android:textSize">18sp</item>
<item name="android:textColor">@android:color/suggestion_highlight_text</item>
@@ -1651,6 +1659,9 @@
<item name="android:background">@null</item>
</style>
+ <style name="Widget.Holo.ActivityChooserView" parent="Widget.ActivityChooserView">
+ </style>
+
<style name="Widget.Holo.ImageWell" parent="Widget.ImageWell">
</style>
@@ -2071,6 +2082,10 @@
<style name="Widget.Holo.Light.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
</style>
+ <style name="Widget.Holo.Light.ActivityChooserView" parent="Widget.Holo.ActivityChooserView">
+ <item name="android:background">@android:drawable/ab_share_pack_holo_light</item>
+ </style>
+
<style name="Widget.Holo.Light.ImageWell" parent="Widget.ImageWell">
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 6f98e02..d19c97f 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -124,6 +124,8 @@
<item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeight</item>
<item name="textAppearanceListItem">?android:attr/textAppearanceLarge</item>
<item name="textAppearanceListItemSmall">?android:attr/textAppearanceLarge</item>
+ <item name="listPreferredItemPaddingLeft">6dip</item>
+ <item name="listPreferredItemPaddingRight">6dip</item>
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
@@ -269,7 +271,8 @@
<item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.QuickContactBadgeSmall.WindowLarge</item>
<item name="listPopupWindowStyle">@android:style/Widget.ListPopupWindow</item>
<item name="popupMenuStyle">@android:style/Widget.PopupMenu</item>
-
+ <item name="activityChooserViewStyle">@android:style/Widget.ActivityChooserView</item>
+
<!-- Preference styles -->
<item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item>
<item name="preferenceCategoryStyle">@android:style/Preference.Category</item>
@@ -923,6 +926,8 @@
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
<item name="textAppearanceListItemSmall">?android:attr/textAppearanceMedium</item>
+ <item name="listPreferredItemPaddingLeft">8dip</item>
+ <item name="listPreferredItemPaddingRight">8dip</item>
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
@@ -1062,6 +1067,7 @@
<item name="listPopupWindowStyle">@android:style/Widget.Holo.ListPopupWindow</item>
<item name="popupMenuStyle">@android:style/Widget.Holo.PopupMenu</item>
<item name="stackViewStyle">@android:style/Widget.Holo.StackView</item>
+ <item name="activityChooserViewStyle">@android:style/Widget.Holo.ActivityChooserView</item>
<!-- Preference styles -->
<item name="preferenceScreenStyle">@android:style/Preference.Holo.PreferenceScreen</item>
@@ -1227,6 +1233,8 @@
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
<item name="textAppearanceListItemSmall">?android:attr/textAppearanceMedium</item>
+ <item name="listPreferredItemPaddingLeft">8dip</item>
+ <item name="listPreferredItemPaddingRight">8dip</item>
<!-- @hide -->
<item name="searchResultListItemHeight">58dip</item>
@@ -1366,6 +1374,7 @@
<item name="listPopupWindowStyle">@android:style/Widget.Holo.Light.ListPopupWindow</item>
<item name="popupMenuStyle">@android:style/Widget.Holo.Light.PopupMenu</item>
<item name="stackViewStyle">@android:style/Widget.Holo.StackView</item>
+ <item name="activityChooserViewStyle">@android:style/Widget.Holo.Light.ActivityChooserView</item>
<!-- Preference styles -->
<item name="preferenceScreenStyle">@android:style/Preference.Holo.PreferenceScreen</item>
@@ -1531,6 +1540,9 @@
<item name="textAppearance">@android:style/TextAppearance.Holo</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Inverse</item>
+
+ <item name="listPreferredItemPaddingLeft">16dip</item>
+ <item name="listPreferredItemPaddingRight">16dip</item>
</style>
<!-- Variation of Theme.Holo.Dialog that has a nice minumum width for
@@ -1620,6 +1632,9 @@
<item name="textAppearance">@android:style/TextAppearance.Holo.Light</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
+
+ <item name="listPreferredItemPaddingLeft">16dip</item>
+ <item name="listPreferredItemPaddingRight">16dip</item>
</style>
<!-- Variation of Theme.Holo.Light.Dialog that has a nice minumum width for
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index 66ed104..a837294 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -37,6 +37,188 @@
public static final int MPERSP_1 = 7; //!< use with getValues/setValues
public static final int MPERSP_2 = 8; //!< use with getValues/setValues
+ /** @hide */
+ public static Matrix IDENTITY_MATRIX = new Matrix() {
+ void oops() {
+ throw new IllegalStateException("Matrix can not be modified");
+ }
+
+ @Override
+ public void set(Matrix src) {
+ oops();
+ }
+
+ @Override
+ public void reset() {
+ oops();
+ }
+
+ @Override
+ public void setTranslate(float dx, float dy) {
+ oops();
+ }
+
+ @Override
+ public void setScale(float sx, float sy, float px, float py) {
+ oops();
+ }
+
+ @Override
+ public void setScale(float sx, float sy) {
+ oops();
+ }
+
+ @Override
+ public void setRotate(float degrees, float px, float py) {
+ oops();
+ }
+
+ @Override
+ public void setRotate(float degrees) {
+ oops();
+ }
+
+ @Override
+ public void setSinCos(float sinValue, float cosValue, float px, float py) {
+ oops();
+ }
+
+ @Override
+ public void setSinCos(float sinValue, float cosValue) {
+ oops();
+ }
+
+ @Override
+ public void setSkew(float kx, float ky, float px, float py) {
+ oops();
+ }
+
+ @Override
+ public void setSkew(float kx, float ky) {
+ oops();
+ }
+
+ @Override
+ public boolean setConcat(Matrix a, Matrix b) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preTranslate(float dx, float dy) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preScale(float sx, float sy, float px, float py) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preScale(float sx, float sy) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preRotate(float degrees, float px, float py) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preRotate(float degrees) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preSkew(float kx, float ky, float px, float py) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preSkew(float kx, float ky) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean preConcat(Matrix other) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postTranslate(float dx, float dy) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postScale(float sx, float sy, float px, float py) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postScale(float sx, float sy) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postRotate(float degrees, float px, float py) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postRotate(float degrees) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postSkew(float kx, float ky, float px, float py) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postSkew(float kx, float ky) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean postConcat(Matrix other) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex,
+ int pointCount) {
+ oops();
+ return false;
+ }
+
+ @Override
+ public void setValues(float[] values) {
+ oops();
+ }
+ };
+
/**
* @hide
*/
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 803bffb..a73403b 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -62,12 +62,17 @@
private:
// current locale (like "ja_JP"), created/destroyed with strdup()/free()
char *mLocale;
+ char *mSkipList;
+ int *mSkipIndex;
MediaScanResult doProcessDirectory(
char *path, int pathRemaining, MediaScannerClient &client, bool noMedia);
MediaScanResult doProcessDirectoryEntry(
char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
struct dirent* entry, char* fileSpot);
+ void loadSkipList();
+ bool shouldSkipDirectory(char *path);
+
MediaScanner(const MediaScanner &);
MediaScanner &operator=(const MediaScanner &);
@@ -103,4 +108,3 @@
}; // namespace android
#endif // MEDIASCANNER_H
-
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 41f8593..19dedfc 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaScanner"
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <media/mediascanner.h>
@@ -26,11 +27,14 @@
namespace android {
MediaScanner::MediaScanner()
- : mLocale(NULL) {
+ : mLocale(NULL), mSkipList(NULL), mSkipIndex(NULL) {
+ loadSkipList();
}
MediaScanner::~MediaScanner() {
setLocale(NULL);
+ free(mSkipList);
+ free(mSkipIndex);
}
void MediaScanner::setLocale(const char *locale) {
@@ -47,6 +51,33 @@
return mLocale;
}
+void MediaScanner::loadSkipList() {
+ mSkipList = (char *)malloc(PROPERTY_VALUE_MAX * sizeof(char));
+ if (mSkipList) {
+ property_get("testing.mediascanner.skiplist", mSkipList, "");
+ }
+ if (!mSkipList || (strlen(mSkipList) == 0)) {
+ free(mSkipList);
+ mSkipList = NULL;
+ return;
+ }
+ mSkipIndex = (int *)malloc(PROPERTY_VALUE_MAX * sizeof(int));
+ if (mSkipIndex) {
+ // dup it because strtok will modify the string
+ char *skipList = strdup(mSkipList);
+ if (skipList) {
+ char * path = strtok(skipList, ",");
+ int i = 0;
+ while (path) {
+ mSkipIndex[i++] = strlen(path);
+ path = strtok(NULL, ",");
+ }
+ mSkipIndex[i] = -1;
+ free(skipList);
+ }
+ }
+}
+
MediaScanResult MediaScanner::processDirectory(
const char *path, MediaScannerClient &client) {
int pathLength = strlen(path);
@@ -75,12 +106,39 @@
return result;
}
+bool MediaScanner::shouldSkipDirectory(char *path) {
+ if (path && mSkipList && mSkipIndex) {
+ int len = strlen(path);
+ int idx = 0;
+ // track the start position of next path in the comma
+ // separated list obtained from getprop
+ int startPos = 0;
+ while (mSkipIndex[idx] != -1) {
+ // no point to match path name if strlen mismatch
+ if ((len == mSkipIndex[idx])
+ // pick out the path segment from comma separated list
+ // to compare against current path parameter
+ && (strncmp(path, &mSkipList[startPos], len) == 0)) {
+ return true;
+ }
+ startPos += mSkipIndex[idx] + 1; // extra char for the delimiter
+ idx++;
+ }
+ }
+ return false;
+}
+
MediaScanResult MediaScanner::doProcessDirectory(
char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) {
// place to copy file or directory name
char* fileSpot = path + strlen(path);
struct dirent* entry;
+ if (shouldSkipDirectory(path)) {
+ LOGD("Skipping: %s", path);
+ return MEDIA_SCAN_RESULT_OK;
+ }
+
// Treat all files as non-media in directories that contain a ".nomedia" file
if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
strcpy(fileSpot, ".nomedia");
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index fb49d7b..9ab470b 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -50,7 +50,7 @@
// Treat time out as an error if we have not received any output
// buffers after 3 seconds.
-const static int64_t kBufferFilledEventTimeOutUs = 3000000000LL;
+const static int64_t kBufferFilledEventTimeOutNs = 3000000000LL;
struct CodecInfo {
const char *mime;
@@ -2325,9 +2325,14 @@
{
CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
data1, data2);
- CHECK(mFilledBuffers.empty());
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
+ // There is no need to check whether mFilledBuffers is empty or not
+ // when the OMX_EventPortSettingsChanged is not meant for reallocating
+ // the output buffers.
+ if (data1 == kPortIndexOutput) {
+ CHECK(mFilledBuffers.empty());
+ }
onPortSettingsChanged(data1);
} else if (data1 == kPortIndexOutput &&
(data2 == OMX_IndexConfigCommonOutputCrop ||
@@ -3220,7 +3225,7 @@
// for video encoding.
return mBufferFilled.wait(mLock);
}
- status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutUs);
+ status_t err = mBufferFilled.waitRelative(mLock, kBufferFilledEventTimeOutNs);
if (err != OK) {
CODEC_LOGE("Timed out waiting for output buffers: %d/%d",
countBuffersWeOwn(mPortBuffers[kPortIndexInput]),
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
index b1ad315..b1d049e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
@@ -95,6 +95,25 @@
return audioEncoderMap.get(audioEncoder);
}
+ public static int getMinFrameRateForCodec(int codec) {
+ return getMinOrMaxFrameRateForCodec(codec, false);
+ }
+
+ public static int getMaxFrameRateForCodec(int codec) {
+ return getMinOrMaxFrameRateForCodec(codec, true);
+ }
+
+ private static int getMinOrMaxFrameRateForCodec(int codec, boolean max) {
+ for (VideoEncoderCap cap: videoEncoders) {
+ if (cap.mCodec == codec) {
+ if (max) return cap.mMaxFrameRate;
+ else return cap.mMinFrameRate;
+ }
+ }
+ // Should never reach here
+ throw new IllegalArgumentException("Unsupported video codec " + codec);
+ }
+
private MediaProfileReader() {} // Don't call me
private static void initVideoEncoderMap() {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index 82df6690..796b52c 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -247,7 +247,9 @@
mCamera.unlock();
mRecorder.setCamera(mCamera);
Thread.sleep(1000);
- recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263,
+ int codec = MediaRecorder.VideoEncoder.H263;
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
+ recordVideo(frameRate, 352, 288, codec,
MediaRecorder.OutputFormat.THREE_GPP,
MediaNames.RECORDED_PORTRAIT_H263, true);
mCamera.lock();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 0f79515..0b887b9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -365,16 +365,6 @@
assertTrue("H264 playback memory test", memoryResult);
}
- private int getMaxFrameRateForVideoEncoder(int codec) {
- int frameRate = -1;
- for (VideoEncoderCap cap: videoEncoders) {
- if (cap.mCodec == MediaRecorder.VideoEncoder.H263) {
- frameRate = cap.mMaxFrameRate;
- }
- }
- return frameRate;
- }
-
// Test case 4: Capture the memory usage after every 20 video only recorded
@LargeTest
public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
@@ -384,7 +374,7 @@
File videoH263RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoH263RecordOnlyMemoryOut, true));
output.write("H263 video record only\n");
- int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
assertTrue("H263 video recording frame rate", frameRate != -1);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.H263,
@@ -406,7 +396,7 @@
File videoMp4RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoMp4RecordOnlyMemoryOut, true));
output.write("MPEG4 video record only\n");
- int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.MPEG_4_SP);
assertTrue("MPEG4 video recording frame rate", frameRate != -1);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
@@ -428,7 +418,7 @@
File videoRecordAudioMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoRecordAudioMemoryOut, true));
- int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
assertTrue("H263 video recording frame rate", frameRate != -1);
output.write("Audio and h263 video record\n");
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
index 35d0a06..0f0cbf1 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
index 79da092..5e8a116 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
new file mode 100644
index 0000000..efac368
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 55623f0..ee9aa41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1795,30 +1795,34 @@
pw.println(" [" + i + "] icon=" + ic);
}
- pw.println("see the logcat for a dump of the views we have created.");
- // must happen on ui thread
- mHandler.post(new Runnable() {
- public void run() {
- mStatusBarView.getLocationOnScreen(mAbsPos);
- Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
- + ") " + mStatusBarView.getWidth() + "x"
- + mStatusBarView.getHeight());
- mStatusBarView.debug();
+ if (false) {
+ pw.println("see the logcat for a dump of the views we have created.");
+ // must happen on ui thread
+ mHandler.post(new Runnable() {
+ public void run() {
+ mStatusBarView.getLocationOnScreen(mAbsPos);
+ Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+ + ") " + mStatusBarView.getWidth() + "x"
+ + mStatusBarView.getHeight());
+ mStatusBarView.debug();
- mExpandedView.getLocationOnScreen(mAbsPos);
- Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
- + ") " + mExpandedView.getWidth() + "x"
- + mExpandedView.getHeight());
- mExpandedView.debug();
+ mExpandedView.getLocationOnScreen(mAbsPos);
+ Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+ + ") " + mExpandedView.getWidth() + "x"
+ + mExpandedView.getHeight());
+ mExpandedView.debug();
- mTrackingView.getLocationOnScreen(mAbsPos);
- Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
- + ") " + mTrackingView.getWidth() + "x"
- + mTrackingView.getHeight());
- mTrackingView.debug();
- }
- });
+ mTrackingView.getLocationOnScreen(mAbsPos);
+ Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+ + ") " + mTrackingView.getWidth() + "x"
+ + mTrackingView.getHeight());
+ mTrackingView.debug();
+ }
+ });
+ }
}
+
+ mNetworkController.dump(fd, pw, args);
}
void onBarViewAttached() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 3c85814..b50ebcd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -296,6 +296,7 @@
}
mServiceState = state;
updateTelephonySignalStrength();
+ updateDataNetType();
updateDataIcon();
refreshViews();
}
@@ -831,7 +832,12 @@
mHasMobileDataFeature ? mDataSignalIconId : mWifiIconId;
mContentDescriptionCombinedSignal = mHasMobileDataFeature
? mContentDescriptionDataType : mContentDescriptionWifi;
- mDataTypeIconId = 0;
+
+ if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) {
+ mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
+ } else {
+ mDataTypeIconId = 0;
+ }
}
if (DEBUG) {
@@ -969,6 +975,7 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("Network Controller state:");
pw.println(" - telephony ------");
pw.print(" mHspaDataDistinguishable=");
pw.println(mHspaDataDistinguishable);
@@ -982,6 +989,10 @@
pw.println(mDataState);
pw.print(" mDataActivity=");
pw.println(mDataActivity);
+ pw.print(" mDataNetType=");
+ pw.print(mDataNetType);
+ pw.print("/");
+ pw.println(TelephonyManager.getNetworkTypeName(mDataNetType));
pw.print(" mServiceState=");
pw.println(mServiceState);
pw.print(" mNetworkName=");
@@ -989,7 +1000,7 @@
pw.print(" mNetworkNameDefault=");
pw.println(mNetworkNameDefault);
pw.print(" mNetworkNameSeparator=");
- pw.println(mNetworkNameSeparator);
+ pw.println(mNetworkNameSeparator.replace("\n","\\n"));
pw.print(" mPhoneSignalIconId=0x");
pw.print(Integer.toHexString(mPhoneSignalIconId));
pw.print("/");
@@ -1060,7 +1071,7 @@
}
private String getResourceName(int resId) {
- if (resId == 0) {
+ if (resId != 0) {
final Resources res = mContext.getResources();
try {
return res.getResourceName(resId);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index 5911378..e406a0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -218,15 +218,16 @@
private View createInputMethodItem(
final InputMethodInfo imi, final InputMethodSubtype subtype) {
- CharSequence subtypeName = getSubtypeName(imi, subtype);
- CharSequence imiName = getIMIName(imi);
- Drawable icon = getSubtypeIcon(imi, subtype);
- View view = View.inflate(mContext, R.layout.status_bar_input_methods_item, null);
- ImageView subtypeIcon = (ImageView)view.findViewById(R.id.item_icon);
- TextView itemTitle = (TextView)view.findViewById(R.id.item_title);
- TextView itemSubtitle = (TextView)view.findViewById(R.id.item_subtitle);
- ImageView settingsIcon = (ImageView)view.findViewById(R.id.item_settings_icon);
- View subtypeView = view.findViewById(R.id.item_subtype);
+ final CharSequence subtypeName = subtype.overridesImplicitlyEnabledSubtype()
+ ? null : getSubtypeName(imi, subtype);
+ final CharSequence imiName = getIMIName(imi);
+ final Drawable icon = getSubtypeIcon(imi, subtype);
+ final View view = View.inflate(mContext, R.layout.status_bar_input_methods_item, null);
+ final ImageView subtypeIcon = (ImageView)view.findViewById(R.id.item_icon);
+ final TextView itemTitle = (TextView)view.findViewById(R.id.item_title);
+ final TextView itemSubtitle = (TextView)view.findViewById(R.id.item_subtitle);
+ final ImageView settingsIcon = (ImageView)view.findViewById(R.id.item_settings_icon);
+ final View subtypeView = view.findViewById(R.id.item_subtype);
if (subtypeName == null) {
itemTitle.setText(imiName);
itemSubtitle.setVisibility(View.GONE);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 9588a01..cbf1c90 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -24,6 +24,7 @@
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Canvas;
+import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -100,7 +101,9 @@
if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
Resources res = mContext.getResources();
- boolean enableScreenRotation = res.getBoolean(R.bool.config_enableLockScreenRotation);
+ boolean enableScreenRotation =
+ SystemProperties.getBoolean("lockscreen.rot_override",false)
+ || res.getBoolean(R.bool.config_enableLockScreenRotation);
if (mKeyguardHost == null) {
if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
@@ -197,10 +200,10 @@
mScreenOn = false;
if (mKeyguardView != null) {
mKeyguardView.onScreenTurnedOff();
- }
- // When screen is turned off, need to unbind from FaceLock service if we are using FaceLock
- mKeyguardView.stopAndUnbindFromFaceLock();
+ // When screen is turned off, need to unbind from FaceLock service if using FaceLock
+ mKeyguardView.stopAndUnbindFromFaceLock();
+ }
}
public synchronized void onScreenTurnedOn() {
@@ -208,10 +211,10 @@
mScreenOn = true;
if (mKeyguardView != null) {
mKeyguardView.onScreenTurnedOn();
- }
- // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
- mKeyguardView.bindToFaceLock();
+ // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
+ mKeyguardView.bindToFaceLock();
+ }
}
public synchronized void verifyUnlock() {
@@ -248,9 +251,11 @@
public synchronized void hide() {
if (DEBUG) Log.d(TAG, "hide()");
- // When view is hidden, need to unbind from FaceLock service if we are using FaceLock
- // e.g., when device becomes unlocked
- mKeyguardView.stopAndUnbindFromFaceLock();
+ if (mKeyguardView != null) {
+ // When view is hidden, need to unbind from FaceLock service if we are using FaceLock
+ // e.g., when device becomes unlocked
+ mKeyguardView.stopAndUnbindFromFaceLock();
+ }
if (mKeyguardHost != null) {
mKeyguardHost.setVisibility(View.GONE);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 304df72..86671bd 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -189,16 +189,16 @@
static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
static final int STATUS_BAR_LAYER = 15;
static final int STATUS_BAR_PANEL_LAYER = 16;
- // the navigation bar, if available, shows atop most things
- static final int NAVIGATION_BAR_LAYER = 17;
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- static final int VOLUME_OVERLAY_LAYER = 18;
+ static final int VOLUME_OVERLAY_LAYER = 17;
+ // things in here CAN NOT take focus, but are shown on top of everything else.
+ static final int SYSTEM_OVERLAY_LAYER = 18;
+ // the navigation bar, if available, shows atop most things
+ static final int NAVIGATION_BAR_LAYER = 19;
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- static final int DRAG_LAYER = 19;
- // things in here CAN NOT take focus, but are shown on top of everything else.
- static final int SYSTEM_OVERLAY_LAYER = 20;
+ static final int DRAG_LAYER = 20;
static final int SECURE_SYSTEM_OVERLAY_LAYER = 21;
static final int BOOT_PROGRESS_LAYER = 22;
// the (mouse) pointer layer
@@ -894,10 +894,10 @@
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
- lp.flags =
- WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
- WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
lp.format = PixelFormat.TRANSLUCENT;
lp.setTitle("PointerLocation");
WindowManager wm = (WindowManager)
@@ -995,6 +995,7 @@
// These types of windows can't receive input events.
attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
break;
}
}
@@ -1993,6 +1994,13 @@
"Laying out navigation bar window: (%d,%d - %d,%d)",
pf.left, pf.top, pf.right, pf.bottom));
}
+ } else if (attrs.type == TYPE_SECURE_SYSTEM_OVERLAY
+ && ((fl & FLAG_FULLSCREEN) != 0)) {
+ // Fullscreen secure system overlays get what they ask for.
+ pf.left = df.left = mUnrestrictedScreenLeft;
+ pf.top = df.top = mUnrestrictedScreenTop;
+ pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+ pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
} else {
pf.left = df.left = cf.left = mRestrictedScreenLeft;
pf.top = df.top = cf.top = mRestrictedScreenTop;
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 8861bee..38968f9 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -103,6 +103,8 @@
TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17,
TYPE_POINTER = FIRST_SYSTEM_WINDOW+18,
TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19,
+ TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20,
+ TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21,
LAST_SYSTEM_WINDOW = 2999,
};
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d6d3b9d..41af137 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3327,20 +3327,28 @@
boolean didSomething = killPackageProcessesLocked(name, uid, -100,
callerWillRestart, false, doit, evenPersistent);
- for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
+ TaskRecord lastTask = null;
+ for (i=0; i<mMainStack.mHistory.size(); i++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
- if (r.packageName.equals(name)
+ final boolean samePackage = r.packageName.equals(name);
+ if ((samePackage || r.task == lastTask)
&& (r.app == null || evenPersistent || !r.app.persistent)) {
if (!doit) {
return true;
}
didSomething = true;
Slog.i(TAG, " Force finishing activity " + r);
- if (r.app != null) {
- r.app.removed = true;
+ if (samePackage) {
+ if (r.app != null) {
+ r.app.removed = true;
+ }
+ r.app = null;
}
- r.app = null;
- r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
+ lastTask = r.task;
+ if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
+ null, "force-stop")) {
+ i--;
+ }
}
}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index c52142d..fe0e850 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -77,15 +77,15 @@
/**
* Low signal is defined as less than or equal to cut off
*/
- private static final int LOW_SIGNAL_CUTOFF = 1;
+ private static final int LOW_SIGNAL_CUTOFF = 0;
private static final long DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS = 2 * 60 * 1000;
- private static final long DEFAULT_DNS_CHECK_LONG_INTERVAL_MS = 30 * 60 * 1000;
+ private static final long DEFAULT_DNS_CHECK_LONG_INTERVAL_MS = 60 * 60 * 1000;
private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
private static final int DEFAULT_MAX_SSID_BLACKLISTS = 7;
- private static final int DEFAULT_NUM_DNS_PINGS = 15; // Multiple pings to detect setup issues
- private static final int DEFAULT_MIN_DNS_RESPONSES = 3;
+ private static final int DEFAULT_NUM_DNS_PINGS = 5; // Multiple pings to detect setup issues
+ private static final int DEFAULT_MIN_DNS_RESPONSES = 1;
private static final int DEFAULT_DNS_PING_TIMEOUT_MS = 2000;
@@ -95,7 +95,9 @@
private static final String DEFAULT_WALLED_GARDEN_URL =
"http://clients3.google.com/generate_204";
private static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
- private static final int DNS_INTRATEST_PING_INTERVAL = 200; // Long delay to detect setup issues
+ private static final int DNS_INTRATEST_PING_INTERVAL_MS = 200;
+ /* With some router setups, it takes a few hunder milli-seconds before connection is active */
+ private static final int DNS_START_DELAY_MS = 1000;
private static final int BASE = Protocol.BASE_WIFI_WATCHDOG;
@@ -677,7 +679,7 @@
for (int i=0; i < mNumDnsPings; i++) {
for (int j = 0; j < numDnses; j++) {
idDnsMap.put(mDnsPinger.pingDnsAsync(mDnsList.get(j), mDnsPingTimeoutMs,
- DNS_INTRATEST_PING_INTERVAL * i), j);
+ DNS_START_DELAY_MS + DNS_INTRATEST_PING_INTERVAL_MS * i), j);
}
}
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index e2b2249..2f7b927 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -132,6 +132,9 @@
/* User rejected to disable Wi-Fi in order to enable p2p */
private static final int WIFI_DISABLE_USER_REJECT = BASE + 5;
+ /* Airplane mode changed */
+ private static final int AIRPLANE_MODE_CHANGED = BASE + 6;
+
private final boolean mP2pSupported;
private final String mDeviceType;
private String mDeviceName;
@@ -168,6 +171,7 @@
// broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
mContext.registerReceiver(new WifiStateReceiver(), filter);
@@ -187,6 +191,8 @@
} else if (intent.getAction().equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
mWifiApState = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,
WifiManager.WIFI_AP_STATE_DISABLED);
+ } else if (intent.getAction().equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+ mP2pStateMachine.sendMessage(AIRPLANE_MODE_CHANGED);
}
}
}
@@ -352,7 +358,10 @@
case WifiP2pManager.REQUEST_GROUP_INFO:
replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup);
break;
- // Ignore
+ case AIRPLANE_MODE_CHANGED:
+ if (isAirplaneModeOn()) sendMessage(WifiP2pManager.DISABLE_P2P);
+ break;
+ // Ignore
case WIFI_DISABLE_USER_ACCEPT:
case WIFI_DISABLE_USER_REJECT:
case GROUP_NEGOTIATION_TIMED_OUT:
@@ -1266,5 +1275,17 @@
}
}
+ private boolean isAirplaneSensitive() {
+ String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_RADIOS);
+ return airplaneModeRadios == null
+ || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
+ }
+
+ private boolean isAirplaneModeOn() {
+ return isAirplaneSensitive() && Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ }
+
}
}