summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java19
-rw-r--r--core/java/android/app/INotificationManager.aidl3
-rw-r--r--core/java/android/app/Notification.java95
-rw-r--r--core/java/android/hardware/Camera.java76
-rw-r--r--core/java/android/net/nsd/INsdManager.aidl1
-rw-r--r--core/java/android/net/nsd/NsdManager.java53
-rw-r--r--core/java/android/provider/MediaStore.java2
-rw-r--r--core/java/android/provider/Settings.java6
-rw-r--r--core/java/android/view/KeyCharacterMap.java221
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/widget/AbsSeekBar.java2
-rw-r--r--core/java/android/widget/ExpandableListConnector.java28
-rw-r--r--core/java/android/widget/ExpandableListPosition.java4
-rw-r--r--core/java/android/widget/ExpandableListView.java17
14 files changed, 202 insertions, 327 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index eed8aa6..4e340c0 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -426,13 +426,11 @@ public abstract class AccessibilityService extends Service {
throw new IllegalStateException("AccessibilityService not connected."
+ " Did you receive a call of onServiceConnected()?");
}
- AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
- .findAccessibilityNodeInfoByAccessibilityId(connectionId,
- AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+ AccessibilityNodeInfo root = getRootInActiveWindow();
if (root == null) {
return;
}
+
AccessibilityNodeInfo current = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
if (current == null) {
current = root;
@@ -480,6 +478,19 @@ public abstract class AccessibilityService extends Service {
}
/**
+ * Gets the root node in the currently active window if this service
+ * can retrieve window content.
+ *
+ * @return The root node if this service can retrieve window content.
+ */
+ public AccessibilityNodeInfo getRootInActiveWindow() {
+ return AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
+ AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
+ AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+ }
+
+ /**
* Performs a global action. Such an action can be performed
* at any moment regardless of the current application or user
* location in that application. For example going back, going
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 4d5238c..6f95e26 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -34,5 +34,8 @@ interface INotificationManager
void cancelToast(String pkg, ITransientNotification callback);
void enqueueNotificationWithTag(String pkg, String tag, int id, in Notification notification, inout int[] idReceived);
void cancelNotificationWithTag(String pkg, String tag, int id);
+
+ void setNotificationsEnabledForPackage(String pkg, boolean enabled);
+ boolean areNotificationsEnabledForPackage(String pkg);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 22d84f0..b581f99 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -190,12 +190,6 @@ public class Notification implements Parcelable
public RemoteViews contentView;
/**
- * The view that will represent this notification in the pop-up "intruder alert" dialog.
- * @hide
- */
- public RemoteViews intruderView;
-
- /**
* A large-format version of {@link #contentView}, giving the Notification an
* opportunity to show more detail. The system UI may choose to show this
* instead of the normal content view at its discretion.
@@ -590,9 +584,6 @@ public class Notification implements Parcelable
actions = parcel.createTypedArray(Action.CREATOR);
if (parcel.readInt() != 0) {
- intruderView = RemoteViews.CREATOR.createFromParcel(parcel);
- }
- if (parcel.readInt() != 0) {
bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
}
}
@@ -658,9 +649,6 @@ public class Notification implements Parcelable
for(int i=0; i<this.actions.length; i++) {
that.actions[i] = this.actions[i].clone();
}
- if (this.intruderView != null) {
- that.intruderView = this.intruderView.clone();
- }
if (this.bigContentView != null) {
that.bigContentView = this.bigContentView.clone();
}
@@ -755,13 +743,6 @@ public class Notification implements Parcelable
parcel.writeTypedArray(actions, 0);
- if (intruderView != null) {
- parcel.writeInt(1);
- intruderView.writeToParcel(parcel, 0);
- } else {
- parcel.writeInt(0);
- }
-
if (bigContentView != null) {
parcel.writeInt(1);
bigContentView.writeToParcel(parcel, 0);
@@ -942,8 +923,6 @@ public class Notification implements Parcelable
private Bundle mExtras;
private int mPriority;
private ArrayList<Action> mActions = new ArrayList<Action>(3);
- private boolean mCanHasIntruder;
- private boolean mIntruderActionsShowText;
private boolean mUseChronometer;
/**
@@ -1349,38 +1328,6 @@ public class Notification implements Parcelable
return this;
}
- /**
- * Specify whether this notification should pop up as an
- * "intruder alert" (a small window that shares the screen with the
- * current activity). This sort of notification is (as the name implies)
- * very intrusive, so use it sparingly for notifications that require
- * the user's attention.
- *
- * Notes:
- * <ul>
- * <li>Intruder alerts only show when the screen is on.</li>
- * <li>Intruder alerts take precedence over fullScreenIntents.</li>
- * </ul>
- *
- * @param intrude Whether to pop up an intruder alert (default false).
- */
- public Builder setUsesIntruderAlert(boolean intrude) {
- mCanHasIntruder = intrude;
- return this;
- }
-
- /**
- * Control text on intruder alert action buttons. By default, action
- * buttons in intruders do not show textual labels.
- *
- * @param showActionText Whether to show text labels beneath action
- * icons (default false).
- */
- public Builder setIntruderActionsShowText(boolean showActionText) {
- mIntruderActionsShowText = showActionText;
- return this;
- }
-
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
@@ -1506,45 +1453,6 @@ public class Notification implements Parcelable
return applyStandardTemplateWithActions(R.layout.notification_template_base);
}
- private RemoteViews makeIntruderView(boolean showLabels) {
- RemoteViews intruderView = new RemoteViews(mContext.getPackageName(),
- R.layout.notification_intruder_content);
- if (mLargeIcon != null) {
- intruderView.setImageViewBitmap(R.id.icon, mLargeIcon);
- intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
- } else if (mSmallIcon != 0) {
- intruderView.setImageViewResource(R.id.icon, mSmallIcon);
- intruderView.setViewVisibility(R.id.icon, View.VISIBLE);
- } else {
- intruderView.setViewVisibility(R.id.icon, View.GONE);
- }
- if (mContentTitle != null) {
- intruderView.setTextViewText(R.id.title, mContentTitle);
- }
- if (mContentText != null) {
- intruderView.setTextViewText(R.id.text, mContentText);
- }
- if (mActions.size() > 0) {
- intruderView.setViewVisibility(R.id.actions, View.VISIBLE);
- int N = mActions.size();
- if (N>3) N=3;
- final int[] BUTTONS = { R.id.action0, R.id.action1, R.id.action2 };
- for (int i=0; i<N; i++) {
- final Action action = mActions.get(i);
- final int buttonId = BUTTONS[i];
-
- intruderView.setViewVisibility(buttonId, View.VISIBLE);
- intruderView.setTextViewText(buttonId, showLabels ? action.title : null);
- intruderView.setTextViewCompoundDrawables(buttonId, 0, action.icon, 0, 0);
- intruderView.setContentDescription(buttonId, action.title);
- intruderView.setOnClickPendingIntent(buttonId, action.actionIntent);
- }
- } else {
- intruderView.setViewVisibility(R.id.actions, View.GONE);
- }
- return intruderView;
- }
-
private RemoteViews generateActionButton(Action action) {
RemoteViews button = new RemoteViews(mContext.getPackageName(), R.layout.notification_action);
button.setTextViewCompoundDrawables(R.id.action0, action.icon, 0, 0, 0);
@@ -1579,9 +1487,6 @@ public class Notification implements Parcelable
n.ledOffMS = mLedOffMs;
n.defaults = mDefaults;
n.flags = mFlags;
- if (mCanHasIntruder) {
- n.intruderView = makeIntruderView(mIntruderActionsShowText);
- }
n.bigContentView = makeBigContentView();
if (mLedOnMs != 0 && mLedOffMs != 0) {
n.flags |= FLAG_SHOW_LIGHTS;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 640b47b..4fb710e 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -234,48 +234,6 @@ public class Camera {
};
/**
- * Creates a new Camera object to access a particular hardware camera.
- *
- * <p>When <code>force</code> is set to false, this will throw an exception
- * if the same camera is already opened by other clients. If true, the other
- * client will be disconnected from the camera they opened. If the device
- * can only support one camera running at a time, all camera-using clients
- * will be disconnected from their cameras.
- *
- * <p>A camera being held by an application can be taken away by other
- * applications at any time. Before the camera is taken, applications will
- * get {@link #CAMERA_ERROR_RELEASED} and have some time to clean up. Apps
- * receiving this callback must immediately stop video recording and then
- * call {@link #release()} on their camera object. Otherwise, it will be
- * released by the frameworks in a short time. After receiving
- * CAMERA_ERROR_RELEASED, apps should not call any method except <code>
- * release</code> and {@link #isReleased()}. After a camera is taken away,
- * all methods will throw exceptions except <code>isReleased</code> and
- * <code>release</code>. Apps can use <code>isReleased</code> to see if the
- * camera has been taken away. If the camera is taken away, the apps can
- * silently finish themselves or show a dialog.
- *
- * <p>Applications with android.permission.KEEP_CAMERA can request to keep
- * the camera. That is, the camera will not be taken by other applications
- * while it is opened. The permission can only be obtained by trusted
- * platform applications, such as those implementing lock screen security
- * features.
- *
- * @param cameraId the hardware camera to access, between 0 and
- * {@link #getNumberOfCameras()}-1.
- * @param force true to take the ownership from the existing client if the
- * camera has been opened by other clients.
- * @param keep true if the applications do not want other apps to take the
- * camera. Only the apps with android.permission.KEEP_CAMERA can keep
- * the camera.
- * @return a new Camera object, connected, locked and ready for use.
- * @hide
- */
- public static Camera open(int cameraId, boolean force, boolean keep) {
- return new Camera(cameraId, force, keep);
- }
-
- /**
* Creates a new Camera object to access a particular hardware camera. If
* the same camera is opened by other applications, this will throw a
* RuntimeException.
@@ -305,7 +263,7 @@ public class Camera {
* @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
*/
public static Camera open(int cameraId) {
- return new Camera(cameraId, false, false);
+ return new Camera(cameraId);
}
/**
@@ -320,13 +278,13 @@ public class Camera {
for (int i = 0; i < numberOfCameras; i++) {
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
- return new Camera(i, false, false);
+ return new Camera(i);
}
}
return null;
}
- Camera(int cameraId, boolean force, boolean keep) {
+ Camera(int cameraId) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
@@ -343,7 +301,7 @@ public class Camera {
mEventHandler = null;
}
- native_setup(new WeakReference<Camera>(this), cameraId, force, keep);
+ native_setup(new WeakReference<Camera>(this), cameraId);
}
/**
@@ -356,8 +314,7 @@ public class Camera {
release();
}
- private native final void native_setup(Object camera_this, int cameraId,
- boolean force, boolean keep);
+ private native final void native_setup(Object camera_this, int cameraId);
private native final void native_release();
@@ -372,18 +329,6 @@ public class Camera {
}
/**
- * Whether the camera is released. When any camera method throws an
- * exception, applications can use this to check whether the camera has been
- * taken by other clients. If true, it means other clients have taken the
- * camera. The applications can silently finish themselves or show a dialog.
- *
- * @return whether the camera is released.
- * @see #open(int, boolean, boolean)
- * @hide
- */
- public native final boolean isReleased();
-
- /**
* Unlocks the camera to allow another process to access it.
* Normally, the camera is locked to the process with an active Camera
* object until {@link #release()} is called. To allow rapid handoff
@@ -1377,17 +1322,6 @@ public class Camera {
public static final int CAMERA_ERROR_UNKNOWN = 1;
/**
- * Camera was released because another client has opened the camera. The
- * application should call {@link #release()} after getting this. The apps
- * should not call any method except <code>release</code> and {@link #isReleased()}
- * after this.
- *
- * @see Camera.ErrorCallback
- * @hide
- */
- public static final int CAMERA_ERROR_RELEASED = 2;
-
- /**
* Media server died. In this case, the application must release the
* Camera object and instantiate a new one.
* @see Camera.ErrorCallback
diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl
index 077a675..3361a7b 100644
--- a/core/java/android/net/nsd/INsdManager.aidl
+++ b/core/java/android/net/nsd/INsdManager.aidl
@@ -26,4 +26,5 @@ import android.os.Messenger;
interface INsdManager
{
Messenger getMessenger();
+ void setEnabled(boolean enable);
}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index dac8d20..ecf5e20 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -16,6 +16,8 @@
package android.net.nsd;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -133,6 +135,40 @@ public class NsdManager {
private static final String TAG = "NsdManager";
INsdManager mService;
+ /**
+ * Broadcast intent action to indicate whether network service discovery is
+ * enabled or disabled. An extra {@link #EXTRA_NSD_STATE} provides the state
+ * information as int.
+ *
+ * @see #EXTRA_NSD_STATE
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_NSD_STATE_CHANGED =
+ "android.net.nsd.STATE_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether network service discovery is enabled
+ * or disabled. Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
+ *
+ * @see #NSD_STATE_DISABLED
+ * @see #NSD_STATE_ENABLED
+ */
+ public static final String EXTRA_NSD_STATE = "nsd_state";
+
+ /**
+ * Network service discovery is disabled
+ *
+ * @see #NSD_STATE_CHANGED_ACTION
+ */
+ public static final int NSD_STATE_DISABLED = 1;
+
+ /**
+ * Network service discovery is enabled
+ *
+ * @see #NSD_STATE_CHANGED_ACTION
+ */
+ public static final int NSD_STATE_ENABLED = 2;
+
private static final int BASE = Protocol.BASE_NSD_MANAGER;
/** @hide */
@@ -188,6 +224,12 @@ public class NsdManager {
/** @hide */
public static final int STOP_RESOLVE_SUCCEEDED = BASE + 23;
+ /** @hide */
+ public static final int ENABLE = BASE + 24;
+ /** @hide */
+ public static final int DISABLE = BASE + 25;
+
+
/**
* Create a new Nsd instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -312,8 +354,8 @@ public class NsdManager {
private DnsSdResolveListener mDnsSdResolveListener;
private ActionListener mDnsSdStopResolveListener;
- AsyncChannel mAsyncChannel;
- ServiceHandler mHandler;
+ private AsyncChannel mAsyncChannel;
+ private ServiceHandler mHandler;
class ServiceHandler extends Handler {
ServiceHandler(Looper looper) {
super(looper);
@@ -594,6 +636,13 @@ public class NsdManager {
c.mAsyncChannel.sendMessage(STOP_RESOLVE);
}
+ /** Internal use only @hide */
+ public void setEnabled(boolean enabled) {
+ try {
+ mService.setEnabled(enabled);
+ } catch (RemoteException e) { }
+ }
+
/**
* Get a reference to NetworkService handler. This is used to establish
* an AsyncChannel communication with the service
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 38945c2..79d0144 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -306,13 +306,11 @@ public final class MediaStore {
/**
* The width of the image/video in pixels.
- * @hide
*/
public static final String WIDTH = "width";
/**
* The height of the image/video in pixels.
- * @hide
*/
public static final String HEIGHT = "height";
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6dfbb2f..3a5fdd1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3277,6 +3277,12 @@ public final class Settings {
"wifi_mobile_data_transition_wakelock_timeout_ms";
/**
+ * Whether network service discovery is enabled.
+ * @hide
+ */
+ public static final String NSD_ON = "nsd_on";
+
+ /**
* Whether background data usage is allowed by the user. See
* ConnectivityManager for more info.
*/
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index d8d5185..1c61c6c 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -24,6 +24,7 @@ import android.util.SparseIntArray;
import android.hardware.input.InputManager;
import java.lang.Character;
+import java.text.Normalizer;
/**
* Describes the keys provided by a keyboard device and their associated labels.
@@ -149,9 +150,22 @@ public class KeyCharacterMap implements Parcelable {
/* Characters used to display placeholders for dead keys. */
private static final int ACCENT_ACUTE = '\u00B4';
+ private static final int ACCENT_BREVE = '\u02D8';
+ private static final int ACCENT_CARON = '\u02C7';
+ private static final int ACCENT_CEDILLA = '\u00B8';
+ private static final int ACCENT_COMMA_ABOVE = '\u1FBD';
+ private static final int ACCENT_COMMA_ABOVE_RIGHT = '\u02BC';
+ private static final int ACCENT_DOT_ABOVE = '\u02D9';
+ private static final int ACCENT_DOUBLE_ACUTE = '\u02DD';
private static final int ACCENT_GRAVE = '\u02CB';
private static final int ACCENT_CIRCUMFLEX = '\u02C6';
+ private static final int ACCENT_MACRON = '\u00AF';
+ private static final int ACCENT_MACRON_BELOW = '\u02CD';
+ private static final int ACCENT_OGONEK = '\u02DB';
+ private static final int ACCENT_REVERSED_COMMA_ABOVE = '\u02BD';
+ private static final int ACCENT_RING_ABOVE = '\u02DA';
private static final int ACCENT_TILDE = '\u02DC';
+ private static final int ACCENT_TURNED_COMMA_ABOVE = '\u02BB';
private static final int ACCENT_UMLAUT = '\u00A8';
/* Legacy dead key display characters used in previous versions of the API.
@@ -161,136 +175,66 @@ public class KeyCharacterMap implements Parcelable {
private static final int ACCENT_TILDE_LEGACY = '~';
/**
- * Maps Unicode combining diacritical to display-form dead key
- * (display character shifted left 16 bits).
+ * Maps Unicode combining diacritical to display-form dead key.
*/
- private static final SparseIntArray COMBINING = new SparseIntArray();
+ private static final SparseIntArray sCombiningToAccent = new SparseIntArray();
+ private static final SparseIntArray sAccentToCombining = new SparseIntArray();
static {
- COMBINING.put('\u0300', ACCENT_GRAVE);
- COMBINING.put('\u0301', ACCENT_ACUTE);
- COMBINING.put('\u0302', ACCENT_CIRCUMFLEX);
- COMBINING.put('\u0303', ACCENT_TILDE);
- COMBINING.put('\u0308', ACCENT_UMLAUT);
+ addCombining('\u0300', ACCENT_GRAVE);
+ addCombining('\u0301', ACCENT_ACUTE);
+ addCombining('\u0302', ACCENT_CIRCUMFLEX);
+ addCombining('\u0303', ACCENT_TILDE);
+ addCombining('\u0304', ACCENT_MACRON);
+ addCombining('\u0306', ACCENT_BREVE);
+ addCombining('\u0307', ACCENT_DOT_ABOVE);
+ addCombining('\u0308', ACCENT_UMLAUT);
+ //addCombining('\u0309', ACCENT_HOOK_ABOVE);
+ addCombining('\u030A', ACCENT_RING_ABOVE);
+ addCombining('\u030B', ACCENT_DOUBLE_ACUTE);
+ addCombining('\u030C', ACCENT_CARON);
+ //addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE);
+ //addCombining('\u030E', ACCENT_DOUBLE_VERTICAL_LINE_ABOVE);
+ //addCombining('\u030F', ACCENT_DOUBLE_GRAVE);
+ //addCombining('\u0310', ACCENT_CANDRABINDU);
+ //addCombining('\u0311', ACCENT_INVERTED_BREVE);
+ addCombining('\u0312', ACCENT_TURNED_COMMA_ABOVE);
+ addCombining('\u0313', ACCENT_COMMA_ABOVE);
+ addCombining('\u0314', ACCENT_REVERSED_COMMA_ABOVE);
+ addCombining('\u0315', ACCENT_COMMA_ABOVE_RIGHT);
+ //addCombining('\u031B', ACCENT_HORN);
+ //addCombining('\u0323', ACCENT_DOT_BELOW);
+ //addCombining('\u0326', ACCENT_COMMA_BELOW);
+ addCombining('\u0327', ACCENT_CEDILLA);
+ addCombining('\u0328', ACCENT_OGONEK);
+ //addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW);
+ addCombining('\u0331', ACCENT_MACRON_BELOW);
+ //addCombining('\u0342', ACCENT_PERISPOMENI);
+ //addCombining('\u0344', ACCENT_DIALYTIKA_TONOS);
+ //addCombining('\u0345', ACCENT_YPOGEGRAMMENI);
+
+ // One-way mappings to equivalent preferred accents.
+ sCombiningToAccent.append('\u0340', ACCENT_GRAVE);
+ sCombiningToAccent.append('\u0341', ACCENT_ACUTE);
+ sCombiningToAccent.append('\u0343', ACCENT_COMMA_ABOVE);
+
+ // One-way legacy mappings to preserve compatibility with older applications.
+ sAccentToCombining.append(ACCENT_GRAVE_LEGACY, '\u0300');
+ sAccentToCombining.append(ACCENT_CIRCUMFLEX_LEGACY, '\u0302');
+ sAccentToCombining.append(ACCENT_TILDE_LEGACY, '\u0303');
+ }
+
+ private static void addCombining(int combining, int accent) {
+ sCombiningToAccent.append(combining, accent);
+ sAccentToCombining.append(accent, combining);
}
/**
- * Maps combinations of (display-form) dead key and second character
+ * Maps combinations of (display-form) combining key and second character
* to combined output character.
+ * These mappings are derived from the Unicode NFC tables as needed.
*/
- private static final SparseIntArray DEAD = new SparseIntArray();
- static {
- addDeadChar(ACCENT_ACUTE, 'A', '\u00C1');
- addDeadChar(ACCENT_ACUTE, 'C', '\u0106');
- addDeadChar(ACCENT_ACUTE, 'E', '\u00C9');
- addDeadChar(ACCENT_ACUTE, 'G', '\u01F4');
- addDeadChar(ACCENT_ACUTE, 'I', '\u00CD');
- addDeadChar(ACCENT_ACUTE, 'K', '\u1E30');
- addDeadChar(ACCENT_ACUTE, 'L', '\u0139');
- addDeadChar(ACCENT_ACUTE, 'M', '\u1E3E');
- addDeadChar(ACCENT_ACUTE, 'N', '\u0143');
- addDeadChar(ACCENT_ACUTE, 'O', '\u00D3');
- addDeadChar(ACCENT_ACUTE, 'P', '\u1E54');
- addDeadChar(ACCENT_ACUTE, 'R', '\u0154');
- addDeadChar(ACCENT_ACUTE, 'S', '\u015A');
- addDeadChar(ACCENT_ACUTE, 'U', '\u00DA');
- addDeadChar(ACCENT_ACUTE, 'W', '\u1E82');
- addDeadChar(ACCENT_ACUTE, 'Y', '\u00DD');
- addDeadChar(ACCENT_ACUTE, 'Z', '\u0179');
- addDeadChar(ACCENT_ACUTE, 'a', '\u00E1');
- addDeadChar(ACCENT_ACUTE, 'c', '\u0107');
- addDeadChar(ACCENT_ACUTE, 'e', '\u00E9');
- addDeadChar(ACCENT_ACUTE, 'g', '\u01F5');
- addDeadChar(ACCENT_ACUTE, 'i', '\u00ED');
- addDeadChar(ACCENT_ACUTE, 'k', '\u1E31');
- addDeadChar(ACCENT_ACUTE, 'l', '\u013A');
- addDeadChar(ACCENT_ACUTE, 'm', '\u1E3F');
- addDeadChar(ACCENT_ACUTE, 'n', '\u0144');
- addDeadChar(ACCENT_ACUTE, 'o', '\u00F3');
- addDeadChar(ACCENT_ACUTE, 'p', '\u1E55');
- addDeadChar(ACCENT_ACUTE, 'r', '\u0155');
- addDeadChar(ACCENT_ACUTE, 's', '\u015B');
- addDeadChar(ACCENT_ACUTE, 'u', '\u00FA');
- addDeadChar(ACCENT_ACUTE, 'w', '\u1E83');
- addDeadChar(ACCENT_ACUTE, 'y', '\u00FD');
- addDeadChar(ACCENT_ACUTE, 'z', '\u017A');
- addDeadChar(ACCENT_CIRCUMFLEX, 'A', '\u00C2');
- addDeadChar(ACCENT_CIRCUMFLEX, 'C', '\u0108');
- addDeadChar(ACCENT_CIRCUMFLEX, 'E', '\u00CA');
- addDeadChar(ACCENT_CIRCUMFLEX, 'G', '\u011C');
- addDeadChar(ACCENT_CIRCUMFLEX, 'H', '\u0124');
- addDeadChar(ACCENT_CIRCUMFLEX, 'I', '\u00CE');
- addDeadChar(ACCENT_CIRCUMFLEX, 'J', '\u0134');
- addDeadChar(ACCENT_CIRCUMFLEX, 'O', '\u00D4');
- addDeadChar(ACCENT_CIRCUMFLEX, 'S', '\u015C');
- addDeadChar(ACCENT_CIRCUMFLEX, 'U', '\u00DB');
- addDeadChar(ACCENT_CIRCUMFLEX, 'W', '\u0174');
- addDeadChar(ACCENT_CIRCUMFLEX, 'Y', '\u0176');
- addDeadChar(ACCENT_CIRCUMFLEX, 'Z', '\u1E90');
- addDeadChar(ACCENT_CIRCUMFLEX, 'a', '\u00E2');
- addDeadChar(ACCENT_CIRCUMFLEX, 'c', '\u0109');
- addDeadChar(ACCENT_CIRCUMFLEX, 'e', '\u00EA');
- addDeadChar(ACCENT_CIRCUMFLEX, 'g', '\u011D');
- addDeadChar(ACCENT_CIRCUMFLEX, 'h', '\u0125');
- addDeadChar(ACCENT_CIRCUMFLEX, 'i', '\u00EE');
- addDeadChar(ACCENT_CIRCUMFLEX, 'j', '\u0135');
- addDeadChar(ACCENT_CIRCUMFLEX, 'o', '\u00F4');
- addDeadChar(ACCENT_CIRCUMFLEX, 's', '\u015D');
- addDeadChar(ACCENT_CIRCUMFLEX, 'u', '\u00FB');
- addDeadChar(ACCENT_CIRCUMFLEX, 'w', '\u0175');
- addDeadChar(ACCENT_CIRCUMFLEX, 'y', '\u0177');
- addDeadChar(ACCENT_CIRCUMFLEX, 'z', '\u1E91');
- addDeadChar(ACCENT_GRAVE, 'A', '\u00C0');
- addDeadChar(ACCENT_GRAVE, 'E', '\u00C8');
- addDeadChar(ACCENT_GRAVE, 'I', '\u00CC');
- addDeadChar(ACCENT_GRAVE, 'N', '\u01F8');
- addDeadChar(ACCENT_GRAVE, 'O', '\u00D2');
- addDeadChar(ACCENT_GRAVE, 'U', '\u00D9');
- addDeadChar(ACCENT_GRAVE, 'W', '\u1E80');
- addDeadChar(ACCENT_GRAVE, 'Y', '\u1EF2');
- addDeadChar(ACCENT_GRAVE, 'a', '\u00E0');
- addDeadChar(ACCENT_GRAVE, 'e', '\u00E8');
- addDeadChar(ACCENT_GRAVE, 'i', '\u00EC');
- addDeadChar(ACCENT_GRAVE, 'n', '\u01F9');
- addDeadChar(ACCENT_GRAVE, 'o', '\u00F2');
- addDeadChar(ACCENT_GRAVE, 'u', '\u00F9');
- addDeadChar(ACCENT_GRAVE, 'w', '\u1E81');
- addDeadChar(ACCENT_GRAVE, 'y', '\u1EF3');
- addDeadChar(ACCENT_TILDE, 'A', '\u00C3');
- addDeadChar(ACCENT_TILDE, 'E', '\u1EBC');
- addDeadChar(ACCENT_TILDE, 'I', '\u0128');
- addDeadChar(ACCENT_TILDE, 'N', '\u00D1');
- addDeadChar(ACCENT_TILDE, 'O', '\u00D5');
- addDeadChar(ACCENT_TILDE, 'U', '\u0168');
- addDeadChar(ACCENT_TILDE, 'V', '\u1E7C');
- addDeadChar(ACCENT_TILDE, 'Y', '\u1EF8');
- addDeadChar(ACCENT_TILDE, 'a', '\u00E3');
- addDeadChar(ACCENT_TILDE, 'e', '\u1EBD');
- addDeadChar(ACCENT_TILDE, 'i', '\u0129');
- addDeadChar(ACCENT_TILDE, 'n', '\u00F1');
- addDeadChar(ACCENT_TILDE, 'o', '\u00F5');
- addDeadChar(ACCENT_TILDE, 'u', '\u0169');
- addDeadChar(ACCENT_TILDE, 'v', '\u1E7D');
- addDeadChar(ACCENT_TILDE, 'y', '\u1EF9');
- addDeadChar(ACCENT_UMLAUT, 'A', '\u00C4');
- addDeadChar(ACCENT_UMLAUT, 'E', '\u00CB');
- addDeadChar(ACCENT_UMLAUT, 'H', '\u1E26');
- addDeadChar(ACCENT_UMLAUT, 'I', '\u00CF');
- addDeadChar(ACCENT_UMLAUT, 'O', '\u00D6');
- addDeadChar(ACCENT_UMLAUT, 'U', '\u00DC');
- addDeadChar(ACCENT_UMLAUT, 'W', '\u1E84');
- addDeadChar(ACCENT_UMLAUT, 'X', '\u1E8C');
- addDeadChar(ACCENT_UMLAUT, 'Y', '\u0178');
- addDeadChar(ACCENT_UMLAUT, 'a', '\u00E4');
- addDeadChar(ACCENT_UMLAUT, 'e', '\u00EB');
- addDeadChar(ACCENT_UMLAUT, 'h', '\u1E27');
- addDeadChar(ACCENT_UMLAUT, 'i', '\u00EF');
- addDeadChar(ACCENT_UMLAUT, 'o', '\u00F6');
- addDeadChar(ACCENT_UMLAUT, 't', '\u1E97');
- addDeadChar(ACCENT_UMLAUT, 'u', '\u00FC');
- addDeadChar(ACCENT_UMLAUT, 'w', '\u1E85');
- addDeadChar(ACCENT_UMLAUT, 'x', '\u1E8D');
- addDeadChar(ACCENT_UMLAUT, 'y', '\u00FF');
- }
+ private static final SparseIntArray sDeadKeyCache = new SparseIntArray();
+ private static final StringBuilder sDeadKeyBuilder = new StringBuilder();
public static final Parcelable.Creator<KeyCharacterMap> CREATOR =
new Parcelable.Creator<KeyCharacterMap>() {
@@ -387,7 +331,7 @@ public class KeyCharacterMap implements Parcelable {
metaState = KeyEvent.normalizeMetaState(metaState);
char ch = nativeGetCharacter(mPtr, keyCode, metaState);
- int map = COMBINING.get(ch);
+ int map = sCombiningToAccent.get(ch);
if (map != 0) {
return map | COMBINING_ACCENT;
} else {
@@ -503,14 +447,25 @@ public class KeyCharacterMap implements Parcelable {
* @return The combined character, or 0 if the characters cannot be combined.
*/
public static int getDeadChar(int accent, int c) {
- if (accent == ACCENT_CIRCUMFLEX_LEGACY) {
- accent = ACCENT_CIRCUMFLEX;
- } else if (accent == ACCENT_GRAVE_LEGACY) {
- accent = ACCENT_GRAVE;
- } else if (accent == ACCENT_TILDE_LEGACY) {
- accent = ACCENT_TILDE;
+ int combining = sAccentToCombining.get(accent);
+ if (combining == 0) {
+ return 0;
}
- return DEAD.get((accent << 16) | c);
+
+ final int combination = (combining << 16) | c;
+ int combined;
+ synchronized (sDeadKeyCache) {
+ combined = sDeadKeyCache.get(combination, -1);
+ if (combined == -1) {
+ sDeadKeyBuilder.setLength(0);
+ sDeadKeyBuilder.append((char)c);
+ sDeadKeyBuilder.append((char)combining);
+ String result = Normalizer.normalize(sDeadKeyBuilder, Normalizer.Form.NFC);
+ combined = result.length() == 1 ? result.charAt(0) : 0;
+ sDeadKeyCache.put(combination, combined);
+ }
+ }
+ return combined;
}
/**
@@ -723,10 +678,6 @@ public class KeyCharacterMap implements Parcelable {
return 0;
}
- private static void addDeadChar(int accent, int c, char combinedResult) {
- DEAD.put((accent << 16) | c, combinedResult);
- }
-
/**
* Thrown by {@link KeyCharacterMap#load} when a key character map could not be loaded.
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bd054bc..7e5fe63 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12297,7 +12297,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
final int flags = parent.mGroupFlags;
final boolean initialized = a.isInitialized();
if (!initialized) {
- a.initialize(mRight - mLeft, mBottom - mTop, getWidth(), getHeight());
+ a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
onAnimationStart();
}
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index ca5648a..ae68794 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -123,7 +123,7 @@ public abstract class AbsSeekBar extends ProgressBar {
invalidate();
if (needUpdate) {
updateThumbPos(getWidth(), getHeight());
- if (thumb.isStateful()) {
+ if (thumb != null && thumb.isStateful()) {
// Note that if the states are different this won't work.
// For now, let's consider that an app bug.
int[] state = getDrawableState();
diff --git a/core/java/android/widget/ExpandableListConnector.java b/core/java/android/widget/ExpandableListConnector.java
index 2ff6b70..bda64ba 100644
--- a/core/java/android/widget/ExpandableListConnector.java
+++ b/core/java/android/widget/ExpandableListConnector.java
@@ -372,7 +372,8 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
@Override
public boolean isEnabled(int flatListPos) {
- final ExpandableListPosition pos = getUnflattenedPos(flatListPos).position;
+ final PositionMetadata metadata = getUnflattenedPos(flatListPos);
+ final ExpandableListPosition pos = metadata.position;
boolean retValue;
if (pos.type == ExpandableListPosition.CHILD) {
@@ -382,7 +383,7 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
retValue = true;
}
- pos.recycle();
+ metadata.recycle();
return retValue;
}
@@ -461,7 +462,8 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
@Override
public int getItemViewType(int flatListPos) {
- final ExpandableListPosition pos = getUnflattenedPos(flatListPos).position;
+ final PositionMetadata metadata = getUnflattenedPos(flatListPos);
+ final ExpandableListPosition pos = metadata.position;
int retValue;
if (mExpandableListAdapter instanceof HeterogeneousExpandableList) {
@@ -481,7 +483,7 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
}
}
- pos.recycle();
+ metadata.recycle();
return retValue;
}
@@ -590,8 +592,10 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
* @param groupPos position of the group to collapse
*/
boolean collapseGroup(int groupPos) {
- PositionMetadata pm = getFlattenedPos(ExpandableListPosition.obtain(
- ExpandableListPosition.GROUP, groupPos, -1, -1));
+ ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
+ ExpandableListPosition.GROUP, groupPos, -1, -1);
+ PositionMetadata pm = getFlattenedPos(elGroupPos);
+ elGroupPos.recycle();
if (pm == null) return false;
boolean retValue = collapseGroup(pm);
@@ -631,8 +635,10 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
* @param groupPos the group to be expanded
*/
boolean expandGroup(int groupPos) {
- PositionMetadata pm = getFlattenedPos(ExpandableListPosition.obtain(
- ExpandableListPosition.GROUP, groupPos, -1, -1));
+ ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
+ ExpandableListPosition.GROUP, groupPos, -1, -1);
+ PositionMetadata pm = getFlattenedPos(elGroupPos);
+ elGroupPos.recycle();
boolean retValue = expandGroup(pm);
pm.recycle();
return retValue;
@@ -971,7 +977,10 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
public int groupInsertIndex;
private void resetState() {
- position = null;
+ if (position != null) {
+ position.recycle();
+ position = null;
+ }
groupMetadata = null;
groupInsertIndex = 0;
}
@@ -1005,6 +1014,7 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
}
public void recycle() {
+ resetState();
synchronized (sPool) {
if (sPool.size() < MAX_POOL_SIZE) {
sPool.add(this);
diff --git a/core/java/android/widget/ExpandableListPosition.java b/core/java/android/widget/ExpandableListPosition.java
index e8d6113..bb68da6 100644
--- a/core/java/android/widget/ExpandableListPosition.java
+++ b/core/java/android/widget/ExpandableListPosition.java
@@ -125,6 +125,10 @@ class ExpandableListPosition {
return elp;
}
+ /**
+ * Do not call this unless you obtained this via ExpandableListPosition.obtain().
+ * PositionMetadata will handle recycling its own children.
+ */
public void recycle() {
synchronized (sPool) {
if (sPool.size() < MAX_POOL_SIZE) {
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index c2d8bda..a746370 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -326,7 +326,6 @@ public class ExpandableListView extends ListView {
indicator.draw(canvas);
}
}
-
pos.recycle();
}
@@ -613,8 +612,10 @@ public class ExpandableListView extends ListView {
* was already expanded, this will return false)
*/
public boolean expandGroup(int groupPos, boolean animate) {
- PositionMetadata pm = mConnector.getFlattenedPos(ExpandableListPosition.obtain(
- ExpandableListPosition.GROUP, groupPos, -1, -1));
+ ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
+ ExpandableListPosition.GROUP, groupPos, -1, -1);
+ PositionMetadata pm = mConnector.getFlattenedPos(elGroupPos);
+ elGroupPos.recycle();
boolean retValue = mConnector.expandGroup(pm);
if (mOnGroupExpandListener != null) {
@@ -776,8 +777,10 @@ public class ExpandableListView extends ListView {
* @return The flat list position for the given child or group.
*/
public int getFlatListPosition(long packedPosition) {
- PositionMetadata pm = mConnector.getFlattenedPos(ExpandableListPosition
- .obtainPosition(packedPosition));
+ ExpandableListPosition elPackedPos = ExpandableListPosition
+ .obtainPosition(packedPosition);
+ PositionMetadata pm = mConnector.getFlattenedPos(elPackedPos);
+ elPackedPos.recycle();
final int flatListPosition = pm.position.flatListPos;
pm.recycle();
return getAbsoluteFlatPosition(flatListPosition);
@@ -988,11 +991,11 @@ public class ExpandableListView extends ListView {
final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
PositionMetadata pm = mConnector.getUnflattenedPos(adjustedPosition);
ExpandableListPosition pos = pm.position;
- pm.recycle();
id = getChildOrGroupId(pos);
long packedPosition = pos.getPackedPosition();
- pos.recycle();
+
+ pm.recycle();
return new ExpandableListContextMenuInfo(view, packedPosition, id);
}