Merge "Release the constraint on the requested version." into jb-dev
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 7ffa575..53b41d5 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -299,7 +299,23 @@
callback = state.uriCallback;
}
if (callback != null) {
- return callback.createBeamUris(mDefaultEvent);
+ uris = callback.createBeamUris(mDefaultEvent);
+ if (uris != null) {
+ for (Uri uri : uris) {
+ if (uri == null) {
+ Log.e(TAG, "Uri not allowed to be null.");
+ return null;
+ }
+ String scheme = uri.getScheme();
+ if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
+ !scheme.equalsIgnoreCase("content"))) {
+ Log.e(TAG, "Uri needs to have " +
+ "either scheme file or scheme content");
+ return null;
+ }
+ }
+ }
+ return uris;
} else {
return uris;
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 7bf9feb..4464d58 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -584,17 +584,138 @@
}
}
- //TODO: make sure NFC service has permission for URI
- //TODO: see if we will eventually support multiple URIs
- //TODO: javadoc
+ /**
+ * Set one or more {@link Uri}s to send using Android Beam (TM). Every
+ * Uri you provide must have either scheme 'file' or scheme 'content'.
+ *
+ * <p>For the data provided through this method, Android Beam tries to
+ * switch to alternate transports such as Bluetooth to achieve a fast
+ * transfer speed. Hence this method is very suitable
+ * for transferring large files such as pictures or songs.
+ *
+ * <p>The receiving side will store the content of each Uri in
+ * a file and present a notification to the user to open the file
+ * with a {@link android.content.Intent} with action
+ * {@link android.content.Intent#ACTION_VIEW}.
+ * If multiple URIs are sent, the {@link android.content.Intent} will refer
+ * to the first of the stored files.
+ *
+ * <p>This method may be called at any time before {@link Activity#onDestroy},
+ * but the URI(s) are only made available for Android Beam when the
+ * specified activity(s) are in resumed (foreground) state. The recommended
+ * approach is to call this method during your Activity's
+ * {@link Activity#onCreate} - see sample
+ * code below. This method does not immediately perform any I/O or blocking work,
+ * so is safe to call on your main thread.
+ *
+ * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
+ * have priority over both {@link #setNdefPushMessage} and
+ * {@link #setNdefPushMessageCallback}.
+ *
+ * <p>If {@link #setBeamPushUris} is called with a null Uri array,
+ * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
+ * then the Uri push will be completely disabled for the specified activity(s).
+ *
+ * <p>Code example:
+ * <pre>
+ * protected void onCreate(Bundle savedInstanceState) {
+ * super.onCreate(savedInstanceState);
+ * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ * if (nfcAdapter == null) return; // NFC not available on this device
+ * nfcAdapter.setBeamPushUris(new Uri[] {uri1, uri2}, this);
+ * }
+ * </pre>
+ * And that is it. Only one call per activity is necessary. The Android
+ * OS will automatically release its references to the Uri(s) and the
+ * Activity object when it is destroyed if you follow this pattern.
+ *
+ * <p>If your Activity wants to dynamically supply Uri(s),
+ * then set a callback using {@link #setBeamPushUrisCallback} instead
+ * of using this method.
+ *
+ * <p class="note">Do not pass in an Activity that has already been through
+ * {@link Activity#onDestroy}. This is guaranteed if you call this API
+ * during {@link Activity#onCreate}.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param uris an array of Uri(s) to push over Android Beam
+ * @param activity activity for which the Uri(s) will be pushed
+ */
public void setBeamPushUris(Uri[] uris, Activity activity) {
if (activity == null) {
throw new NullPointerException("activity cannot be null");
}
+ if (uris != null) {
+ for (Uri uri : uris) {
+ if (uri == null) throw new NullPointerException("Uri not " +
+ "allowed to be null");
+ String scheme = uri.getScheme();
+ if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
+ !scheme.equalsIgnoreCase("content"))) {
+ throw new IllegalArgumentException("URI needs to have " +
+ "either scheme file or scheme content");
+ }
+ }
+ }
mNfcActivityManager.setNdefPushContentUri(activity, uris);
}
- // TODO javadoc
+ /**
+ * Set a callback that will dynamically generate one or more {@link Uri}s
+ * to send using Android Beam (TM). Every Uri the callback provides
+ * must have either scheme 'file' or scheme 'content'.
+ *
+ * <p>For the data provided through this callback, Android Beam tries to
+ * switch to alternate transports such as Bluetooth to achieve a fast
+ * transfer speed. Hence this method is very suitable
+ * for transferring large files such as pictures or songs.
+ *
+ * <p>The receiving side will store the content of each Uri in
+ * a file and present a notification to the user to open the file
+ * with a {@link android.content.Intent} with action
+ * {@link android.content.Intent#ACTION_VIEW}.
+ * If multiple URIs are sent, the {@link android.content.Intent} will refer
+ * to the first of the stored files.
+ *
+ * <p>This method may be called at any time before {@link Activity#onDestroy},
+ * but the URI(s) are only made available for Android Beam when the
+ * specified activity(s) are in resumed (foreground) state. The recommended
+ * approach is to call this method during your Activity's
+ * {@link Activity#onCreate} - see sample
+ * code below. This method does not immediately perform any I/O or blocking work,
+ * so is safe to call on your main thread.
+ *
+ * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
+ * have priority over both {@link #setNdefPushMessage} and
+ * {@link #setNdefPushMessageCallback}.
+ *
+ * <p>If {@link #setBeamPushUris} is called with a null Uri array,
+ * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
+ * then the Uri push will be completely disabled for the specified activity(s).
+ *
+ * <p>Code example:
+ * <pre>
+ * protected void onCreate(Bundle savedInstanceState) {
+ * super.onCreate(savedInstanceState);
+ * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
+ * if (nfcAdapter == null) return; // NFC not available on this device
+ * nfcAdapter.setBeamPushUrisCallback(callback, this);
+ * }
+ * </pre>
+ * And that is it. Only one call per activity is necessary. The Android
+ * OS will automatically release its references to the Uri(s) and the
+ * Activity object when it is destroyed if you follow this pattern.
+ *
+ * <p class="note">Do not pass in an Activity that has already been through
+ * {@link Activity#onDestroy}. This is guaranteed if you call this API
+ * during {@link Activity#onCreate}.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param callback callback, or null to disable
+ * @param activity activity for which the Uri(s) will be pushed
+ */
public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
if (activity == null) {
throw new NullPointerException("activity cannot be null");
@@ -663,6 +784,10 @@
* {@link Activity#onDestroy}. This is guaranteed if you call this API
* during {@link Activity#onCreate}.
*
+ * <p class="note">For sending large content such as pictures and songs,
+ * consider using {@link #setBeamPushUris}, which switches to alternate transports
+ * such as Bluetooth to achieve a fast transfer rate.
+ *
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param message NDEF message to push over NFC, or null to disable
@@ -753,7 +878,9 @@
* <p class="note">Do not pass in an Activity that has already been through
* {@link Activity#onDestroy}. This is guaranteed if you call this API
* during {@link Activity#onCreate}.
- *
+ * <p class="note">For sending large content such as pictures and songs,
+ * consider using {@link #setBeamPushUris}, which switches to alternate transports
+ * such as Bluetooth to achieve a fast transfer rate.
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param callback callback, or null to disable
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d62f513..d94275b 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -691,13 +691,6 @@
*/
public static final int FLAG_NEEDS_MENU_KEY = 0x08000000;
- /** Window flag: *sigh* The lock screen wants to continue running its
- * animation while it is fading. A kind-of hack to allow this. Maybe
- * in the future we just make this the default behavior.
- *
- * {@hide} */
- public static final int FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000;
-
/** Window flag: special flag to limit the size of the window to be
* original size ([320x480] x density). Used to create window for applications
* running under compatibility mode.
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index ee24e5e..add0fbb 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -100,7 +100,6 @@
import android.webkit.WebViewCore.EventHub;
import android.webkit.WebViewCore.TextFieldInitData;
import android.webkit.WebViewCore.TextSelectionData;
-import android.webkit.WebViewCore.TouchHighlightData;
import android.webkit.WebViewCore.WebKitHitTest;
import android.widget.AbsoluteLayout;
import android.widget.Adapter;
@@ -274,6 +273,7 @@
newCursorPosition -= text.length() - limitedText.length();
}
super.setComposingText(limitedText, newCursorPosition);
+ updateSelection();
if (limitedText != text) {
restartInput();
int lastCaret = start + limitedText.length();
@@ -286,19 +286,44 @@
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
setComposingText(text, newCursorPosition);
- int cursorPosition = Selection.getSelectionEnd(getEditable());
- setComposingRegion(cursorPosition, cursorPosition);
+ finishComposingText();
return true;
}
@Override
public boolean deleteSurroundingText(int leftLength, int rightLength) {
- Editable editable = getEditable();
- int cursorPosition = Selection.getSelectionEnd(editable);
- int startDelete = Math.max(0, cursorPosition - leftLength);
- int endDelete = Math.min(editable.length(),
- cursorPosition + rightLength);
- setNewText(startDelete, endDelete, "");
+ // This code is from BaseInputConnection#deleteSurroundText.
+ // We have to delete the same text in webkit.
+ Editable content = getEditable();
+ int a = Selection.getSelectionStart(content);
+ int b = Selection.getSelectionEnd(content);
+
+ if (a > b) {
+ int tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+ int ca = getComposingSpanStart(content);
+ int cb = getComposingSpanEnd(content);
+ if (cb < ca) {
+ int tmp = ca;
+ ca = cb;
+ cb = tmp;
+ }
+ if (ca != -1 && cb != -1) {
+ if (ca < a) a = ca;
+ if (cb > b) b = cb;
+ }
+
+ int endDelete = Math.min(content.length(), b + rightLength);
+ if (endDelete > b) {
+ setNewText(b, endDelete, "");
+ }
+ int startDelete = Math.max(0, a - leftLength);
+ if (startDelete < a) {
+ setNewText(startDelete, a, "");
+ }
return super.deleteSurroundingText(leftLength, rightLength);
}
@@ -411,6 +436,46 @@
outAttrs.imeOptions = mImeOptions;
outAttrs.hintText = mHint;
outAttrs.initialCapsMode = getCursorCapsMode(InputType.TYPE_CLASS_TEXT);
+
+ Editable editable = getEditable();
+ int selectionStart = Selection.getSelectionStart(editable);
+ int selectionEnd = Selection.getSelectionEnd(editable);
+ if (selectionStart < 0 || selectionEnd < 0) {
+ selectionStart = editable.length();
+ selectionEnd = selectionStart;
+ }
+ outAttrs.initialSelStart = selectionStart;
+ outAttrs.initialSelEnd = selectionEnd;
+ }
+
+ @Override
+ public boolean setSelection(int start, int end) {
+ boolean result = super.setSelection(start, end);
+ updateSelection();
+ return result;
+ }
+
+ @Override
+ public boolean setComposingRegion(int start, int end) {
+ boolean result = super.setComposingRegion(start, end);
+ updateSelection();
+ return result;
+ }
+
+ /**
+ * Send the selection and composing spans to the IME.
+ */
+ private void updateSelection() {
+ Editable editable = getEditable();
+ int selectionStart = Selection.getSelectionStart(editable);
+ int selectionEnd = Selection.getSelectionEnd(editable);
+ int composingStart = getComposingSpanStart(editable);
+ int composingEnd = getComposingSpanEnd(editable);
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ imm.updateSelection(mWebView, selectionStart, selectionEnd,
+ composingStart, composingEnd);
+ }
}
/**
@@ -4965,6 +5030,7 @@
private void adjustSelectionCursors() {
if (mIsCaretSelection) {
+ syncSelectionCursors();
return; // no need to swap left and right handles.
}
diff --git a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png
index 2fc475b..9c5147e 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png
index 5adecf1..9c5147e 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
index 457fa84..a257e26 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
index c3cfc29..a257e26 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
index d0e1806..dd999d6 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
index c30506d..dd999d6 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
index 9106687..ea54380 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
index 2bdda56..ea54380 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png
index 0787d16..3d7c236 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png
index 0157e68..3d7c236 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
index 51b14d0..82f05d6 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
index d68568a..82f05d6 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
index 6bf153a..9bc7a68 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
index 0d98983..9bc7a68 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
index 3cee7b8..670dc2e 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
index 43a7c4c..670dc2e 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png
index a0e6b20..ca48bd8 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png
index 88235fe..ca48bd8 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png
index 04fb9a1..c3d80f0 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png
index 06a14f3..c3d80f0 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png
index af7d631..df236df 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png
index d6ab3ea..df236df 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png
index 5a8e807..4acb32b 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png
index 392f3dc..4acb32b 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/switch_track_holo_dark.xml b/core/res/res/drawable/switch_track_holo_dark.xml
index c9a940d..5f796c1 100644
--- a/core/res/res/drawable/switch_track_holo_dark.xml
+++ b/core/res/res/drawable/switch_track_holo_dark.xml
@@ -15,7 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:drawable="@drawable/switch_bg_disabled_holo_dark" />
<item android:state_focused="true" android:drawable="@drawable/switch_bg_focused_holo_dark" />
<item android:drawable="@drawable/switch_bg_holo_dark" />
</selector>
diff --git a/core/res/res/drawable/switch_track_holo_light.xml b/core/res/res/drawable/switch_track_holo_light.xml
index 98e53b5..39bee37 100644
--- a/core/res/res/drawable/switch_track_holo_light.xml
+++ b/core/res/res/drawable/switch_track_holo_light.xml
@@ -15,7 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:drawable="@drawable/switch_bg_disabled_holo_light" />
<item android:state_focused="true" android:drawable="@drawable/switch_bg_focused_holo_light" />
<item android:drawable="@drawable/switch_bg_holo_light" />
</selector>
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index d165b5e..aa29444 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3699,38 +3699,15 @@
}
/**
- * The minimum duration during which a user must press to trigger voice-based interactions
- */
- private final static int MEDIABUTTON_LONG_PRESS_DURATION_MS = 300;
- /**
- * The different states of the state machine to handle the launch of voice-based interactions,
- * stored in mVoiceButtonState.
- */
- private final static int VOICEBUTTON_STATE_IDLE = 0;
- private final static int VOICEBUTTON_STATE_DOWN = 1;
- private final static int VOICEBUTTON_STATE_DOWN_IGNORE_NEW = 2;
- /**
- * The different actions after state transitions on mVoiceButtonState.
+ * The different actions performed in response to a voice button key event.
*/
private final static int VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS = 1;
private final static int VOICEBUTTON_ACTION_START_VOICE_INPUT = 2;
private final static int VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS = 3;
private final Object mVoiceEventLock = new Object();
- private int mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
- private long mVoiceButtonDownTime = 0;
-
- /**
- * Log an error when an unexpected action is encountered in the state machine to filter
- * key events.
- * @param keyAction the unexpected action of the key event being filtered
- * @param stateName the string corresponding to the state in which the error occurred
- */
- private static void logErrorForKeyAction(int keyAction, String stateName) {
- Log.e(TAG, "unexpected action "
- + KeyEvent.actionToString(keyAction)
- + " in " + stateName + " state");
- }
+ private boolean mVoiceButtonDown;
+ private boolean mVoiceButtonHandled;
/**
* Filter key events that may be used for voice-based interactions
@@ -3740,67 +3717,32 @@
* is dispatched.
*/
private void filterVoiceInputKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
+ if (DEBUG_RC) {
+ Log.v(TAG, "voice input key event: " + keyEvent + ", needWakeLock=" + needWakeLock);
+ }
+
int voiceButtonAction = VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS;
int keyAction = keyEvent.getAction();
synchronized (mVoiceEventLock) {
- // state machine on mVoiceButtonState
- switch (mVoiceButtonState) {
-
- case VOICEBUTTON_STATE_IDLE:
- if (keyAction == KeyEvent.ACTION_DOWN) {
- mVoiceButtonDownTime = keyEvent.getDownTime();
- // valid state transition
- mVoiceButtonState = VOICEBUTTON_STATE_DOWN;
- } else if (keyAction == KeyEvent.ACTION_UP) {
- // no state transition
- // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
- } else {
- logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_IDLE");
+ if (keyAction == KeyEvent.ACTION_DOWN) {
+ if (keyEvent.getRepeatCount() == 0) {
+ // initial down
+ mVoiceButtonDown = true;
+ mVoiceButtonHandled = false;
+ } else if (mVoiceButtonDown && !mVoiceButtonHandled
+ && (keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
+ // long-press, start voice-based interactions
+ mVoiceButtonHandled = true;
+ voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT;
+ }
+ } else if (keyAction == KeyEvent.ACTION_UP) {
+ if (mVoiceButtonDown) {
+ // voice button up
+ mVoiceButtonDown = false;
+ if (!mVoiceButtonHandled && !keyEvent.isCanceled()) {
+ voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS;
}
- break;
-
- case VOICEBUTTON_STATE_DOWN:
- if ((keyEvent.getEventTime() - mVoiceButtonDownTime)
- >= MEDIABUTTON_LONG_PRESS_DURATION_MS) {
- // press was long enough, start voice-based interactions, regardless of
- // whether this was a DOWN or UP key event
- voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT;
- if (keyAction == KeyEvent.ACTION_UP) {
- // done tracking the key press, so transition back to idle state
- mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
- } else if (keyAction == KeyEvent.ACTION_DOWN) {
- // no need to observe the upcoming key events
- mVoiceButtonState = VOICEBUTTON_STATE_DOWN_IGNORE_NEW;
- } else {
- logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN");
- }
- } else {
- if (keyAction == KeyEvent.ACTION_UP) {
- // press wasn't long enough, simulate complete key press
- voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS;
- // not tracking the key press anymore, so transition back to idle state
- mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
- } else if (keyAction == KeyEvent.ACTION_DOWN) {
- // no state transition
- // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
- } else {
- logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN");
- }
- }
- break;
-
- case VOICEBUTTON_STATE_DOWN_IGNORE_NEW:
- if (keyAction == KeyEvent.ACTION_UP) {
- // done tracking the key press, so transition back to idle state
- mVoiceButtonState = VOICEBUTTON_STATE_IDLE;
- // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
- } else if (keyAction == KeyEvent.ACTION_DOWN) {
- // no state transition: we've already launched voice-based interactions
- // action is still VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS
- } else {
- logErrorForKeyAction(keyAction, "VOICEBUTTON_STATE_DOWN_IGNORE_NEW");
- }
- break;
+ }
}
}//synchronized (mVoiceEventLock)
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 7f432bf..504bb63 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -117,7 +117,6 @@
final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
- | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
| WindowManager.LayoutParams.FLAG_SLIPPERY
/*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index b1558c7..1f03d17 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -376,11 +376,7 @@
@Override
public void onReceive(Context context, Intent intent) {
mAirplaneModeOn.set(isAirplaneModeOn());
- /* On airplane mode disable, restore wifi state if necessary */
- if (!mAirplaneModeOn.get() && (testAndClearWifiSavedState() ||
- mPersistWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE)) {
- persistWifiState(true);
- }
+ handleAirplaneModeToggled(mAirplaneModeOn.get());
updateWifiState();
}
},
@@ -447,7 +443,10 @@
boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();
Slog.i(TAG, "WifiService starting up with Wi-Fi " +
(wifiEnabled ? "enabled" : "disabled"));
- setWifiEnabled(wifiEnabled);
+
+ // If we are already disabled (could be due to airplane mode), avoid changing persist
+ // state here
+ if (wifiEnabled) setWifiEnabled(wifiEnabled);
mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
makeWifiWatchdogStateMachine(mContext);
@@ -485,26 +484,43 @@
}
}
- private void persistWifiState(boolean enabled) {
- final ContentResolver cr = mContext.getContentResolver();
- boolean airplane = mAirplaneModeOn.get() && isAirplaneToggleable();
- if (enabled) {
- if (airplane) {
- mPersistWifiState.set(WIFI_ENABLED_AIRPLANE_OVERRIDE);
+ private void handleWifiToggled(boolean wifiEnabled) {
+ boolean airplaneEnabled = mAirplaneModeOn.get() && isAirplaneToggleable();
+ if (wifiEnabled) {
+ if (airplaneEnabled) {
+ persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE);
} else {
- mPersistWifiState.set(WIFI_ENABLED);
+ persistWifiState(WIFI_ENABLED);
}
} else {
- if (airplane) {
- mPersistWifiState.set(WIFI_DISABLED_AIRPLANE_ON);
- } else {
- mPersistWifiState.set(WIFI_DISABLED);
- }
+ // When wifi state is disabled, we do not care
+ // if airplane mode is on or not. The scenario of
+ // wifi being disabled due to airplane mode being turned on
+ // is handled handleAirplaneModeToggled()
+ persistWifiState(WIFI_DISABLED);
}
-
- Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, mPersistWifiState.get());
}
+ private void handleAirplaneModeToggled(boolean airplaneEnabled) {
+ if (airplaneEnabled) {
+ // Wifi disabled due to airplane on
+ if (mWifiEnabled) {
+ persistWifiState(WIFI_DISABLED_AIRPLANE_ON);
+ }
+ } else {
+ /* On airplane mode disable, restore wifi state if necessary */
+ if (testAndClearWifiSavedState() ||
+ mPersistWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE) {
+ persistWifiState(WIFI_ENABLED);
+ }
+ }
+ }
+
+ private void persistWifiState(int state) {
+ final ContentResolver cr = mContext.getContentResolver();
+ mPersistWifiState.set(state);
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, state);
+ }
/**
* see {@link android.net.wifi.WifiManager#pingSupplicant()}
@@ -578,12 +594,9 @@
* only CHANGE_WIFI_STATE is enforced
*/
- /* Avoids overriding of airplane state when wifi is already in the expected state */
- if (enable != mWifiEnabled) {
- long ident = Binder.clearCallingIdentity();
- persistWifiState(enable);
- Binder.restoreCallingIdentity(ident);
- }
+ long ident = Binder.clearCallingIdentity();
+ handleWifiToggled(enable);
+ Binder.restoreCallingIdentity(ident);
if (enable) {
if (!mIsReceiverRegistered) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b3ac6f1..f460f9b 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1173,8 +1173,7 @@
if (DEBUG_INPUT_METHOD) {
Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
if (!w.isVisibleOrAdding()) {
- Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurface + " reportDestroy="
- + w.mWinAnimator.mReportDestroySurface
+ Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurface
+ " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
+ " policyVis=" + w.mPolicyVisibility + " attachHid=" + w.mAttachedHidden
+ " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
@@ -2651,7 +2650,7 @@
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
- boolean displayed = false;
+ boolean toBeDisplayed = false;
boolean inTouchMode;
boolean configChanged;
boolean surfaceChanged = false;
@@ -2754,7 +2753,7 @@
}
if (viewVisibility == View.VISIBLE &&
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
- displayed = !win.isVisibleLw();
+ toBeDisplayed = !win.isVisibleLw();
if (win.mExiting) {
winAnimator.cancelExitAnimationForNextAnimationLocked();
win.mExiting = false;
@@ -2766,7 +2765,7 @@
if (oldVisibility == View.GONE) {
winAnimator.mEnterAnimationPending = true;
}
- if (displayed) {
+ if (toBeDisplayed) {
if (win.isDrawnLw() && okToDisplay()) {
winAnimator.applyEnterAnimationLocked();
}
@@ -2792,7 +2791,7 @@
if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
// To change the format, we need to re-build the surface.
winAnimator.destroySurfaceLocked();
- displayed = true;
+ toBeDisplayed = true;
surfaceChanged = true;
}
try {
@@ -2802,8 +2801,6 @@
Surface surface = winAnimator.createSurfaceLocked();
if (surface != null) {
outSurface.copyFrom(surface);
- winAnimator.mReportDestroySurface = false;
- winAnimator.mSurfacePendingDestroy = false;
if (SHOW_TRANSACTIONS) Slog.i(TAG,
" OUT SURFACE " + outSurface + ": copied");
} else {
@@ -2820,7 +2817,7 @@
Binder.restoreCallingIdentity(origId);
return 0;
}
- if (displayed) {
+ if (toBeDisplayed) {
focusMayChange = true;
}
if (win.mAttrs.type == TYPE_INPUT_METHOD
@@ -2845,11 +2842,10 @@
winAnimator.mEnterAnimationPending = false;
if (winAnimator.mSurface != null) {
if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
- + ": mExiting=" + win.mExiting
- + " mSurfacePendingDestroy=" + winAnimator.mSurfacePendingDestroy);
+ + ": mExiting=" + win.mExiting);
// If we are not currently running the exit animation, we
// need to see about starting one.
- if (!win.mExiting || winAnimator.mSurfacePendingDestroy) {
+ if (!win.mExiting) {
surfaceChanged = true;
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
@@ -2857,7 +2853,7 @@
if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
- if (!winAnimator.mSurfacePendingDestroy && win.isWinVisibleLw() &&
+ if (win.isWinVisibleLw() &&
winAnimator.applyAnimationLocked(transit, false)) {
focusMayChange = true;
win.mExiting = true;
@@ -2880,22 +2876,8 @@
}
}
- if (winAnimator.mSurface == null || (win.getAttrs().flags
- & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
- || winAnimator.mSurfacePendingDestroy) {
- // We could be called from a local process, which
- // means outSurface holds its current surface. Ensure the
- // surface object is cleared, but we don't necessarily want
- // it actually destroyed at this point.
- winAnimator.mSurfacePendingDestroy = false;
- outSurface.release();
- if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
- } else if (winAnimator.mSurface != null) {
- if (DEBUG_VISIBILITY) Slog.i(TAG,
- "Keeping surface, will report destroy: " + win);
- winAnimator.mReportDestroySurface = true;
- outSurface.copyFrom(winAnimator.mSurface);
- }
+ outSurface.release();
+ if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
}
if (focusMayChange) {
@@ -2912,7 +2894,7 @@
boolean assignLayers = false;
if (imMayMove) {
- if (moveInputMethodWindowsIfNeededLocked(false) || displayed) {
+ if (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed) {
// Little hack here -- we -should- be able to rely on the
// function to return true if the IME has moved and needs
// its layer recomputed. However, if the IME was hidden
@@ -2934,7 +2916,7 @@
}
configChanged = updateOrientationFromAppTokensLocked(false);
performLayoutAndPlaceSurfacesLocked();
- if (displayed && win.mIsWallpaper) {
+ if (toBeDisplayed && win.mIsWallpaper) {
updateWallpaperOffsetLocked(win, mAppDisplayWidth, mAppDisplayHeight, false);
}
if (win.mAppToken != null) {
@@ -2970,7 +2952,7 @@
Binder.restoreCallingIdentity(origId);
return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
- | (displayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
+ | (toBeDisplayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
| (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0)
| (animating ? WindowManagerImpl.RELAYOUT_RES_ANIMATING : 0);
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 1fd80c2..e2a904f 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -679,8 +679,7 @@
*/
boolean isVisibleOrAdding() {
final AppWindowToken atoken = mAppToken;
- return ((mHasSurface && !mWinAnimator.mReportDestroySurface)
- || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
+ return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
&& mPolicyVisibility && !mAttachedHidden
&& (atoken == null || !atoken.hiddenRequested)
&& !mExiting && !mDestroying;
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 5516dea..355db6e 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -71,8 +71,6 @@
Surface mSurface;
Surface mPendingDestroySurface;
- boolean mReportDestroySurface;
- boolean mSurfacePendingDestroy;
/**
* Set when we have changed the size of the surface, to know that
@@ -561,8 +559,6 @@
Surface createSurfaceLocked() {
if (mSurface == null) {
- mReportDestroySurface = false;
- mSurfacePendingDestroy = false;
if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
"createSurface " + this + ": mDrawState=DRAW_PENDING");
mDrawState = DRAW_PENDING;
@@ -694,7 +690,6 @@
mWin.mAppToken.startingDisplayed = false;
}
- mDrawState = NO_SURFACE;
if (mSurface != null) {
int i = mWin.mChildWindows.size();
@@ -704,17 +699,6 @@
c.mAttachedHidden = true;
}
- if (mReportDestroySurface) {
- mReportDestroySurface = false;
- mSurfacePendingDestroy = true;
- try {
- mWin.mClient.dispatchGetNewSurface();
- // We'll really destroy on the next time around.
- return;
- } catch (RemoteException e) {
- }
- }
-
try {
if (DEBUG_VISIBILITY) {
RuntimeException e = null;
@@ -760,6 +744,7 @@
mSurfaceShown = false;
mSurface = null;
mWin.mHasSurface =false;
+ mDrawState = NO_SURFACE;
}
}
@@ -1147,7 +1132,7 @@
}
} else {
if (DEBUG_ANIM) {
- Slog.v(TAG, "prepareSurface: No changes in animation for " + mWin);
+ // Slog.v(TAG, "prepareSurface: No changes in animation for " + mWin);
}
displayed = true;
}