Merge "Support INVITE w/o SDP."
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index ae41876..9966753 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -69,8 +69,15 @@
* that caused the change in content provider.
* <p>Receivers of the broadcast can use this field to determine if this is
* a self change.
+ * @deprecated {@link #EXTRA_SELF_CHANGE} is now populated instead.
*/
public static final String EXTRA_CHANGED_BY = "com.android.voicemail.extra.CHANGED_BY";
+ /**
+ * Extra included in {@value Intent#ACTION_PROVIDER_CHANGED} and
+ * {@value #ACTION_NEW_VOICEMAIL} broadcast intents to indicate if the receiving
+ * package made this change.
+ */
+ public static final String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE";
/** The mime type for a collection of voicemails. */
public static final String DIR_TYPE =
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 5ee33e1..8e4725f 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -442,7 +442,7 @@
private final Map<String, Uri> mUtterances;
private final Bundle mParams = new Bundle();
private final TtsEngines mEnginesHelper;
- private String mCurrentEngine = null;
+ private volatile String mCurrentEngine = null;
/**
* The constructor for the TextToSpeech class, using the default TTS engine.
@@ -573,6 +573,7 @@
service.setCallback(getPackageName(), null);
service.stop(getPackageName());
mServiceConnection.disconnect();
+ mCurrentEngine = null;
return null;
}
}, null, "shutdown");
@@ -869,6 +870,14 @@
}
/**
+ * @return the engine currently in use by this TextToSpeech instance.
+ * @hide
+ */
+ public String getCurrentEngine() {
+ return mCurrentEngine;
+ }
+
+ /**
* Sets the text-to-speech language.
* The TTS engine will try to use the closest match to the specified
* language as represented by the Locale, but there is no guarantee that the exact same Locale
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index a2019fc..10dd924 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -550,6 +550,26 @@
private void notifyEventListenerLocked(Service service, int eventType) {
IEventListener listener = service.mServiceInterface;
AccessibilityEvent event = service.mPendingEvents.get(eventType);
+
+ // Check for null here because there is a concurrent scenario in which this
+ // happens: 1) A binder thread calls notifyAccessibilityServiceDelayedLocked
+ // which posts a message for dispatching an event. 2) The message is pulled
+ // from the queue by the handler on the service thread and the latter is
+ // just about to acquire the lock and call this method. 3) Now another binder
+ // thread acquires the lock calling notifyAccessibilityServiceDelayedLocked
+ // so the service thread waits for the lock; 4) The binder thread replaces
+ // the event with a more recent one (assume the same event type) and posts a
+ // dispatch request releasing the lock. 5) Now the main thread is unblocked and
+ // dispatches the event which is removed from the pending ones. 6) And ... now
+ // the service thread handles the last message posted by the last binder call
+ // but the event is already dispatched and hence looking it up in the pending
+ // ones yields null. This check is much simpler that keeping count for each
+ // event type of each service to catch such a scenario since only one message
+ // is processed at a time.
+ if (event == null) {
+ return;
+ }
+
service.mPendingEvents.remove(eventType);
try {
if (mSecurityPolicy.canRetrieveWindowContent(service)) {