Merge "Unhide GsmCellLocation.getPsc()." into gingerbread
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f8407c2..d8b5253 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3107,18 +3107,11 @@
/**
* For system applications on userdebug/eng builds, log stack
* traces of disk and network access to dropbox for analysis.
- *
- * Similar logic exists in SystemServer.java.
*/
if ((data.appInfo.flags &
(ApplicationInfo.FLAG_SYSTEM |
- ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0 &&
- !"user".equals(Build.TYPE)) {
- StrictMode.setThreadPolicy(
- StrictMode.DISALLOW_DISK_WRITE |
- StrictMode.DISALLOW_DISK_READ |
- StrictMode.DISALLOW_NETWORK |
- StrictMode.PENALTY_DROPBOX);
+ ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
+ StrictMode.conditionallyEnableDebugLogging();
}
/**
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 9166019..b822b27 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -49,7 +49,6 @@
import org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl;
import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
-import org.apache.harmony.xnet.provider.jsse.SSLParameters;
/**
* SSLSocketFactory implementation with several extra features:
@@ -211,7 +210,8 @@
private SSLSocketFactory makeSocketFactory(TrustManager[] trustManagers) {
try {
OpenSSLContextImpl sslContext = new OpenSSLContextImpl();
- sslContext.engineInit(null, trustManagers, null, mSessionCache, null);
+ sslContext.engineInit(null, trustManagers, null);
+ sslContext.engineGetClientSessionContext().setPersistentCache(mSessionCache);
return sslContext.engineGetSocketFactory();
} catch (KeyManagementException e) {
Log.wtf(TAG, e);
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index c527fe4..4ca5903 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -19,7 +19,7 @@
import com.android.internal.net.DomainNameValidator;
-import org.apache.harmony.xnet.provider.jsse.SSLParameters;
+import org.apache.harmony.xnet.provider.jsse.SSLParametersImpl;
import java.io.IOException;
@@ -191,7 +191,7 @@
// report back to the user.
//
try {
- SSLParameters.getDefaultTrustManager().checkServerTrusted(
+ SSLParametersImpl.getDefaultTrustManager().checkServerTrusted(
newServerCertificates, "RSA");
// no errors!!!
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 8c9d013f..b361dca 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -98,7 +98,8 @@
}
};
- sslContext.engineInit(null, trustManagers, null, cache, null);
+ sslContext.engineInit(null, trustManagers, null);
+ sslContext.engineGetClientSessionContext().setPersistentCache(cache);
synchronized (HttpsConnection.class) {
mSslSocketFactory = sslContext.engineGetSocketFactory();
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index d28148c..5fb1d7c 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -129,7 +129,7 @@
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
- private static final int KEEP_ALIVE = 10;
+ private static final int KEEP_ALIVE = 1;
private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 7f7b02b..f571c42 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -201,6 +201,25 @@
}
/**
+ * Enable DropBox logging for debug phone builds.
+ *
+ * @hide
+ */
+ public static boolean conditionallyEnableDebugLogging() {
+ // For debug builds, log event loop stalls to dropbox for analysis.
+ // Similar logic also appears in ActivityThread.java for system apps.
+ if ("user".equals(Build.TYPE)) {
+ return false;
+ }
+ StrictMode.setThreadPolicy(
+ StrictMode.DISALLOW_DISK_WRITE |
+ StrictMode.DISALLOW_DISK_READ |
+ StrictMode.DISALLOW_NETWORK |
+ StrictMode.PENALTY_DROPBOX);
+ return true;
+ }
+
+ /**
* Parses the BlockGuard policy mask out from the Exception's
* getMessage() String value. Kinda gross, but least
* invasive. :/
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index bba1984..287c136 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -190,7 +190,7 @@
for (int i2=0; i2<N2 && i1<N1; i2++) {
if (uids2[i2] == uids1[i1]) {
N1--;
- if (i1 < N1) System.arraycopy(uids1, i1, uids1, i1-1, N1-i1);
+ if (i1 < N1) System.arraycopy(uids1, i1+1, uids1, i1, N1-i1);
}
while (i1 < N1 && uids2[i2] > uids1[i1]) {
i1++;
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 9a09805..6355a9c 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -943,6 +943,80 @@
}
/**
+ * CalendarCache stores some settings for calendar including the current
+ * time zone for the app. These settings are stored using a key/value
+ * scheme.
+ */
+ public interface CalendarCacheColumns {
+ /**
+ * The key for the setting. Keys are defined in CalendarChache in the
+ * Calendar provider.
+ * TODO Add keys to this file
+ */
+ public static final String KEY = "key";
+
+ /**
+ * The value of the given setting.
+ */
+ public static final String VALUE = "value";
+ }
+
+ public static class CalendarCache implements CalendarCacheColumns {
+ /**
+ * The URI to use for retrieving the properties from the Calendar db.
+ */
+ public static final Uri URI =
+ Uri.parse("content://" + AUTHORITY + "/properties");
+ public static final String[] POJECTION = { KEY, VALUE };
+
+ /**
+ * If updating a property, this must be provided as the selection. All
+ * other selections will fail. For queries this field can be omitted to
+ * retrieve all properties or used to query a single property. Valid
+ * keys include {@link #TIMEZONE_KEY_TYPE},
+ * {@link #TIMEZONE_KEY_INSTANCES}, and
+ * {@link #TIMEZONE_KEY_INSTANCES_PREVIOUS}, though the last one can
+ * only be read, not written.
+ */
+ public static final String WHERE = "key=?";
+
+ /**
+ * They key for updating the use of auto/home time zones in Calendar.
+ * Valid values are {@link #TIMEZONE_TYPE_AUTO} or
+ * {@link #TIMEZONE_TYPE_HOME}.
+ */
+ public static final String TIMEZONE_KEY_TYPE = "timezoneType";
+
+ /**
+ * The key for updating the time zone used by the provider when it
+ * generates the instances table. This should only be written if the
+ * type is set to {@link #TIMEZONE_TYPE_HOME}. A valid time zone id
+ * should be written to this field.
+ */
+ public static final String TIMEZONE_KEY_INSTANCES = "timezoneInstances";
+
+ /**
+ * The key for reading the last time zone set by the user. This should
+ * only be read by apps and it will be automatically updated whenever
+ * {@link #TIMEZONE_KEY_INSTANCES} is updated with
+ * {@link #TIMEZONE_TYPE_HOME} set.
+ */
+ public static final String TIMEZONE_KEY_INSTANCES_PREVIOUS = "timezoneInstancesPrevious";
+
+ /**
+ * The value to write to {@link #TIMEZONE_KEY_TYPE} if the provider
+ * should stay in sync with the device's time zone.
+ */
+ public static final String TIMEZONE_TYPE_AUTO = "auto";
+
+ /**
+ * The value to write to {@link #TIMEZONE_KEY_TYPE} if the provider
+ * should use a fixed time zone set by the user.
+ */
+ public static final String TIMEZONE_TYPE_HOME = "home";
+ }
+
+ /**
* A few Calendar globals are needed in the CalendarProvider for expanding
* the Instances table and these are all stored in the first (and only)
* row of the CalendarMetaData table.
diff --git a/core/java/android/util/CalendarUtils.java b/core/java/android/util/CalendarUtils.java
new file mode 100644
index 0000000..81709d7
--- /dev/null
+++ b/core/java/android/util/CalendarUtils.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.provider.Calendar.CalendarCache;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.Locale;
+
+/**
+ * A class containing utility methods related to Calendar apps.
+ *
+ * @hide
+ */
+public class CalendarUtils {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "CalendarUtils";
+
+ /**
+ * This class contains methods specific to reading and writing time zone
+ * values.
+ */
+ public static class TimeZoneUtils {
+ private static StringBuilder mSB = new StringBuilder(50);
+ private static Formatter mF = new Formatter(mSB, Locale.getDefault());
+ private volatile static boolean mFirstTZRequest = true;
+ private volatile static boolean mTZQueryInProgress = false;
+
+ private volatile static boolean mUseHomeTZ = false;
+ private volatile static String mHomeTZ = Time.getCurrentTimezone();
+
+ private static HashSet<Runnable> mTZCallbacks = new HashSet<Runnable>();
+ private static int mToken = 1;
+ private static AsyncTZHandler mHandler;
+
+ // The name of the shared preferences file. This name must be maintained for historical
+ // reasons, as it's what PreferenceManager assigned the first time the file was created.
+ private final String mPrefsName;
+
+ /**
+ * This is the key used for writing whether or not a home time zone should
+ * be used in the Calendar app to the Calendar Preferences.
+ */
+ public static final String KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled";
+ /**
+ * This is the key used for writing the time zone that should be used if
+ * home time zones are enabled for the Calendar app.
+ */
+ public static final String KEY_HOME_TZ = "preferences_home_tz";
+
+ /**
+ * This is a helper class for handling the async queries and updates for the
+ * time zone settings in Calendar.
+ */
+ private class AsyncTZHandler extends AsyncQueryHandler {
+ public AsyncTZHandler(ContentResolver cr) {
+ super(cr);
+ }
+
+ @Override
+ protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ synchronized (mTZCallbacks) {
+ boolean writePrefs = false;
+ // Check the values in the db
+ int keyColumn = cursor.getColumnIndexOrThrow(CalendarCache.KEY);
+ int valueColumn = cursor.getColumnIndexOrThrow(CalendarCache.VALUE);
+ while(cursor.moveToNext()) {
+ String key = cursor.getString(keyColumn);
+ String value = cursor.getString(valueColumn);
+ if (TextUtils.equals(key, CalendarCache.TIMEZONE_KEY_TYPE)) {
+ boolean useHomeTZ = !TextUtils.equals(
+ value, CalendarCache.TIMEZONE_TYPE_AUTO);
+ if (useHomeTZ != mUseHomeTZ) {
+ writePrefs = true;
+ mUseHomeTZ = useHomeTZ;
+ }
+ } else if (TextUtils.equals(
+ key, CalendarCache.TIMEZONE_KEY_INSTANCES_PREVIOUS)) {
+ if (!TextUtils.isEmpty(value) && !TextUtils.equals(mHomeTZ, value)) {
+ writePrefs = true;
+ mHomeTZ = value;
+ }
+ }
+ }
+ if (writePrefs) {
+ SharedPreferences prefs = getSharedPreferences((Context)cookie, mPrefsName);
+ // Write the prefs
+ setSharedPreference(prefs, KEY_HOME_TZ_ENABLED, mUseHomeTZ);
+ setSharedPreference(prefs, KEY_HOME_TZ, mHomeTZ);
+ }
+
+ mTZQueryInProgress = false;
+ for (Runnable callback : mTZCallbacks) {
+ if (callback != null) {
+ callback.run();
+ }
+ }
+ mTZCallbacks.clear();
+ }
+ }
+ }
+
+ /**
+ * The name of the file where the shared prefs for Calendar are stored
+ * must be provided. All activities within an app should provide the
+ * same preferences name or behavior may become erratic.
+ *
+ * @param prefsName
+ */
+ public TimeZoneUtils(String prefsName) {
+ mPrefsName = prefsName;
+ }
+
+ /**
+ * Formats a date or a time range according to the local conventions.
+ *
+ * This formats a date/time range using Calendar's time zone and the
+ * local conventions for the region of the device.
+ *
+ * @param context the context is required only if the time is shown
+ * @param startMillis the start time in UTC milliseconds
+ * @param endMillis the end time in UTC milliseconds
+ * @param flags a bit mask of options See
+ * {@link DateUtils#formatDateRange(Context, Formatter, long, long, int, String) formatDateRange}
+ * @return a string containing the formatted date/time range.
+ */
+ public String formatDateRange(Context context, long startMillis,
+ long endMillis, int flags) {
+ String date;
+ synchronized (mSB) {
+ mSB.setLength(0);
+ date = DateUtils.formatDateRange(context, mF, startMillis, endMillis, flags,
+ getTimeZone(context, null)).toString();
+ }
+ return date;
+ }
+
+ /**
+ * Writes a new home time zone to the db.
+ *
+ * Updates the home time zone in the db asynchronously and updates
+ * the local cache. Sending a time zone of
+ * {@link CalendarCache#TIMEZONE_TYPE_AUTO} will cause it to be set
+ * to the device's time zone. null or empty tz will be ignored.
+ *
+ * @param context The calling activity
+ * @param timeZone The time zone to set Calendar to, or
+ * {@link CalendarCache#TIMEZONE_TYPE_AUTO}
+ */
+ public void setTimeZone(Context context, String timeZone) {
+ if (TextUtils.isEmpty(timeZone)) {
+ if (DEBUG) {
+ Log.d(TAG, "Empty time zone, nothing to be done.");
+ }
+ return;
+ }
+ boolean updatePrefs = false;
+ synchronized (mTZCallbacks) {
+ if (CalendarCache.TIMEZONE_TYPE_AUTO.equals(timeZone)) {
+ if (mUseHomeTZ) {
+ updatePrefs = true;
+ }
+ mUseHomeTZ = false;
+ } else {
+ if (!mUseHomeTZ || !TextUtils.equals(mHomeTZ, timeZone)) {
+ updatePrefs = true;
+ }
+ mUseHomeTZ = true;
+ mHomeTZ = timeZone;
+ }
+ }
+ if (updatePrefs) {
+ // Write the prefs
+ SharedPreferences prefs = getSharedPreferences(context, mPrefsName);
+ setSharedPreference(prefs, KEY_HOME_TZ_ENABLED, mUseHomeTZ);
+ setSharedPreference(prefs, KEY_HOME_TZ, mHomeTZ);
+
+ // Update the db
+ ContentValues values = new ContentValues();
+ if (mHandler == null) {
+ mHandler = new AsyncTZHandler(context.getContentResolver());
+ }
+
+ mHandler.cancelOperation(mToken);
+
+ // skip 0 so query can use it
+ if (++mToken == 0) {
+ mToken = 1;
+ }
+
+ // Write the use home tz setting
+ String[] selArgs = new String[] { CalendarCache.TIMEZONE_KEY_TYPE };
+ values.put(CalendarCache.VALUE, mUseHomeTZ ? CalendarCache.TIMEZONE_TYPE_HOME
+ : CalendarCache.TIMEZONE_TYPE_AUTO);
+ mHandler.startUpdate(mToken, null, CalendarCache.URI, values, CalendarCache.WHERE,
+ selArgs);
+
+ // If using a home tz write it to the db
+ if (mUseHomeTZ) {
+ selArgs[0] = CalendarCache.TIMEZONE_KEY_INSTANCES;
+ values.clear();
+ values.put(CalendarCache.VALUE, mHomeTZ);
+ mHandler.startUpdate(
+ mToken, null, CalendarCache.URI, values, CalendarCache.WHERE, selArgs);
+ }
+ }
+ }
+
+ /**
+ * Gets the time zone that Calendar should be displayed in
+ *
+ * This is a helper method to get the appropriate time zone for Calendar. If this
+ * is the first time this method has been called it will initiate an asynchronous
+ * query to verify that the data in preferences is correct. The callback supplied
+ * will only be called if this query returns a value other than what is stored in
+ * preferences and should cause the calling activity to refresh anything that
+ * depends on calling this method.
+ *
+ * @param context The calling activity
+ * @param callback The runnable that should execute if a query returns new values
+ * @return The string value representing the time zone Calendar should display
+ */
+ public String getTimeZone(Context context, Runnable callback) {
+ synchronized (mTZCallbacks){
+ if (mFirstTZRequest) {
+ mTZQueryInProgress = true;
+ mFirstTZRequest = false;
+
+ SharedPreferences prefs = getSharedPreferences(context, mPrefsName);
+ mUseHomeTZ = prefs.getBoolean(KEY_HOME_TZ_ENABLED, false);
+ mHomeTZ = prefs.getString(KEY_HOME_TZ, Time.getCurrentTimezone());
+
+ // When the async query returns it should synchronize on
+ // mTZCallbacks, update mUseHomeTZ, mHomeTZ, and the
+ // preferences, set mTZQueryInProgress to false, and call all
+ // the runnables in mTZCallbacks.
+ if (mHandler == null) {
+ mHandler = new AsyncTZHandler(context.getContentResolver());
+ }
+ mHandler.startQuery(0, context, CalendarCache.URI, CalendarCache.POJECTION,
+ null, null, null);
+ }
+ if (mTZQueryInProgress) {
+ mTZCallbacks.add(callback);
+ }
+ }
+ return mUseHomeTZ ? mHomeTZ : Time.getCurrentTimezone();
+ }
+ }
+
+ /**
+ * A helper method for writing a String value to the preferences
+ * asynchronously.
+ *
+ * @param context A context with access to the correct preferences
+ * @param key The preference to write to
+ * @param value The value to write
+ */
+ public static void setSharedPreference(SharedPreferences prefs, String key, String value) {
+// SharedPreferences prefs = getSharedPreferences(context);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(key, value);
+ editor.apply();
+ }
+
+ /**
+ * A helper method for writing a boolean value to the preferences
+ * asynchronously.
+ *
+ * @param context A context with access to the correct preferences
+ * @param key The preference to write to
+ * @param value The value to write
+ */
+ public static void setSharedPreference(SharedPreferences prefs, String key, boolean value) {
+// SharedPreferences prefs = getSharedPreferences(context, prefsName);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(key, value);
+ editor.apply();
+ }
+
+ /** Return a properly configured SharedPreferences instance */
+ public static SharedPreferences getSharedPreferences(Context context, String prefsName) {
+ return context.getSharedPreferences(prefsName, Context.MODE_PRIVATE);
+ }
+}
diff --git a/media/java/android/media/AudioEffect.java b/media/java/android/media/AudioEffect.java
index 35038fa..ae67114 100644
--- a/media/java/android/media/AudioEffect.java
+++ b/media/java/android/media/AudioEffect.java
@@ -16,12 +16,14 @@
package android.media;
-import android.util.Log;
-import java.lang.ref.WeakReference;
-import java.io.IOException;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.util.Log;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.util.UUID;
@@ -839,6 +841,128 @@
byte[] value);
}
+
+ // -------------------------------------------------------------------------
+ // Audio Effect Control panel intents
+ // -------------------------------------------------------------------------
+
+ /**
+ * This intent launches an audio effect control panel UI. The goal of this intent is to enable
+ * separate implementations of music/media player applications and audio effect control
+ * application or services. This will allow platform vendors to offer more advanced control
+ * options for standard effects or control for platform specific effects.
+ * <p>The intent carries a number of extras used by the player application to communicate
+ * necessary pieces of information to the control panel application.
+ * <p>The calling application must use the
+ * {@link android.app.Activity#startActivityForResult(Intent, int)} method to launch the
+ * control panel so that its package name is indicated and used by the control panel
+ * application to keep track of changes for this particular application.
+ * <p>The android.media.EXTRA_AUDIO_SESSION extra will indicate an audio session to which the
+ * audio effects should be applied. If no audio session is specified, either one of the
+ * follownig will happen:
+ * - If an audio session was previously opened by the calling application with
+ * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intent, the effect changes will
+ * be applied to that session.
+ * - If no audio session is opened, the changes will be stored in the package specific storage
+ * area and applied whenever a new audio session is opened by this application.
+ * <p>The android.media.EXTRA_CONTENT_TYPE extra will help the control panel application
+ * customize both the UI layout and the default audio effect settings if none are already
+ * stored for the calling application.
+ * {@hide} pending API council approval
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL =
+ "android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL";
+
+ /**
+ * This intent indicates to the effect control application or service that a new audio session
+ * is opened and requires audio effects to be applied. This is different from
+ * {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} in that no UI should be displayed in
+ * this case. Music player applications can broadcast this intent before starting playback
+ * to make sure that any audio effect settings previously selected by the user are applied.
+ * <p>The effect control application receiving this intent will look for previously stored
+ * settings for the calling application, create all required audio effects and apply the
+ * effect settings to the specified audio session.
+ * <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
+ * audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
+ * <p>If no stored settings are found for the calling application, default settings for the
+ * content type indicated by {@link #EXTRA_CONTENT_TYPE} will be applied. The default settings
+ * for a given content type are platform specific.
+ * {@hide} pending API council approval
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION =
+ "android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION";
+
+ /**
+ * This intent indicates to the effect control application or service that an audio session
+ * is closed and that effects should not be applied anymore.
+ * <p>The effect control application receiving this intent will delete all effects on this
+ * session and store current settings in package specific storage.
+ * <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
+ * audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
+ * <p>It is good practice for applications to broadcast this intent when music playback stops
+ * and/or when exiting to free system resources consumed by audio effect engines.
+ * {@hide} pending API council approval
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION =
+ "android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION";
+
+ /**
+ * This extra indicates the ID of the audio session the effects should be applied to.
+ * <p>The extra value is of type int and is the audio session ID.
+ * @see android.media.MediaPlayer#setAudioSessionId(int) for details on audio sessions.
+ * {@hide} pending API council approval
+ */
+ public static final String EXTRA_AUDIO_SESSION = "android.media.extra.AUDIO_SESSION";
+
+ /**
+ * This extra indicates the package name of the calling application for
+ * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
+ * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
+ * <p>The extra value is a string containing the full package name.
+ * {@hide} pending API council approval
+ */
+ public static final String EXTRA_PACKAGE_NAME = "android.media.extra.PACKAGE_NAME";
+
+ /**
+ * This extra indicates which type of content is played by the application. This information is
+ * used by the effect control application to customize UI and default effect settings.
+ * The content type is one of the following:
+ * <ul>
+ * <li>{@link #CONTENT_TYPE_MUSIC}</li>
+ * <li>{@link #CONTENT_TYPE_MOVIE}</li>
+ * <li>{@link #CONTENT_TYPE_GAME}</li>
+ * <li>{@link #CONTENT_TYPE_VOICE}</li>
+ * </ul>
+ * If omitted, the content type defaults to {@link #CONTENT_TYPE_MUSIC}.
+ * {@hide} pending API council approval
+ */
+ public static final String EXTRA_CONTENT_TYPE = "android.media.extra.CONTENT_TYPE";
+
+ /**
+ * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is music
+ * {@hide} pending API council approval
+ */
+ public static final int CONTENT_TYPE_MUSIC = 0;
+ /**
+ * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is video of movie
+ * {@hide} pending API council approval
+ */
+ public static final int CONTENT_TYPE_MOVIE = 1;
+ /**
+ * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is game audio
+ * {@hide} pending API council approval
+ */
+ public static final int CONTENT_TYPE_GAME = 2;
+ /**
+ * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is voice audio
+ * {@hide} pending API council approval
+ */
+ public static final int CONTENT_TYPE_VOICE = 3;
+
+
// ---------------------------------------------------------
// Inner classes
// --------------------
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index b8403e1..280def9 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1210,7 +1210,6 @@
* effect which can be applied on any sound source that directs a certain amount of its
* energy to this effect. This amount is defined by setAuxEffectSendLevel().
* {@see #setAuxEffectSendLevel(float)}.
- // TODO when AudioEffect is unhidden
* <p>After creating an auxiliary effect (e.g. {@link android.media.EnvironmentalReverb}),
* retrieve its ID with {@link android.media.AudioEffect#getId()} and use it when calling
* this method to attach the player to the effect.
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index af8d7d4..8ab1bb8 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -660,28 +660,38 @@
}
void noteStartWakeLocked(WakeLock wl, WorkSource ws) {
- try {
- if (ws != null) {
- mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
- wl.monitorType);
- } else {
- mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
+ if (wl.monitorType >= 0) {
+ long origId = Binder.clearCallingIdentity();
+ try {
+ if (ws != null) {
+ mBatteryStats.noteStartWakelockFromSource(ws, wl.pid, wl.tag,
+ wl.monitorType);
+ } else {
+ mBatteryStats.noteStartWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
+ }
+ } catch (RemoteException e) {
+ // Ignore
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
- } catch (RemoteException e) {
- // Ignore
}
}
void noteStopWakeLocked(WakeLock wl, WorkSource ws) {
- try {
- if (ws != null) {
- mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
- wl.monitorType);
- } else {
- mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
+ if (wl.monitorType >= 0) {
+ long origId = Binder.clearCallingIdentity();
+ try {
+ if (ws != null) {
+ mBatteryStats.noteStopWakelockFromSource(ws, wl.pid, wl.tag,
+ wl.monitorType);
+ } else {
+ mBatteryStats.noteStopWakelock(wl.uid, wl.pid, wl.tag, wl.monitorType);
+ }
+ } catch (RemoteException e) {
+ // Ignore
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
- } catch (RemoteException e) {
- // Ignore
}
}
@@ -813,21 +823,16 @@
if (ws != null) {
enforceWakeSourcePermission(uid, pid);
}
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (mLocks) {
- int index = mLocks.getIndex(lock);
- if (index < 0) {
- throw new IllegalArgumentException("Wake lock not active");
- }
- WakeLock wl = mLocks.get(index);
- WorkSource oldsource = wl.ws;
- wl.ws = ws != null ? new WorkSource(ws) : null;
- noteStopWakeLocked(wl, oldsource);
- noteStartWakeLocked(wl, ws);
+ synchronized (mLocks) {
+ int index = mLocks.getIndex(lock);
+ if (index < 0) {
+ throw new IllegalArgumentException("Wake lock not active");
}
- } finally {
- Binder.restoreCallingIdentity(ident);
+ WakeLock wl = mLocks.get(index);
+ WorkSource oldsource = wl.ws;
+ wl.ws = ws != null ? new WorkSource(ws) : null;
+ noteStopWakeLocked(wl, oldsource);
+ noteStartWakeLocked(wl, ws);
}
}
@@ -884,14 +889,7 @@
// Unlink the lock from the binder.
wl.binder.unlinkToDeath(wl, 0);
- if (wl.monitorType >= 0) {
- long origId = Binder.clearCallingIdentity();
- try {
- noteStopWakeLocked(wl, wl.ws);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
+ noteStopWakeLocked(wl, wl.ws);
}
private class PokeLock implements IBinder.DeathRecipient
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4a9c9e9..859de46 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -518,14 +518,8 @@
});
// For debug builds, log event loop stalls to dropbox for analysis.
- // Similar logic also appears in ActivityThread.java for system apps.
- if (!"user".equals(Build.TYPE)) {
- Slog.i(TAG, "Enabling StrictMode for system server.");
- StrictMode.setThreadPolicy(
- StrictMode.DISALLOW_DISK_WRITE |
- StrictMode.DISALLOW_DISK_READ |
- StrictMode.DISALLOW_NETWORK |
- StrictMode.PENALTY_DROPBOX);
+ if (StrictMode.conditionallyEnableDebugLogging()) {
+ Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
Looper.loop();
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 124da4e..c837a3a 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -727,9 +727,10 @@
}
}
+ // Called by SystemBackupAgent after files are restored to disk.
void settingsRestored() {
if (DEBUG) Slog.v(TAG, "settingsRestored");
-
+
boolean success = false;
synchronized (mLock) {
loadSettingsLocked();
@@ -766,7 +767,10 @@
mName = "";
WALLPAPER_FILE.delete();
}
- saveSettingsLocked();
+
+ synchronized (mLock) {
+ saveSettingsLocked();
+ }
}
boolean restoreNamedResourceLocked() {
diff --git a/tests/CoreTests/android/core/SSLPerformanceTest.java b/tests/CoreTests/android/core/SSLPerformanceTest.java
index fd87e89..5b5be0a 100644
--- a/tests/CoreTests/android/core/SSLPerformanceTest.java
+++ b/tests/CoreTests/android/core/SSLPerformanceTest.java
@@ -211,17 +211,17 @@
deleteDirectory();
OpenSSLContextImpl sslContext = new OpenSSLContextImpl();
- sslContext.engineInit(null, null, null,
- FileClientSessionCache.usingDirectory(getCacheDirectory()),
- null);
+ sslContext.engineInit(null, null, null);
+ sslContext.engineGetClientSessionContext().setPersistentCache(
+ FileClientSessionCache.usingDirectory(getCacheDirectory()));
// Make sure www.google.com is in the cache.
getVerisignDotCom(sslContext);
// Re-initialize so we hit the file cache.
- sslContext.engineInit(null, null, null,
- FileClientSessionCache.usingDirectory(getCacheDirectory()),
- null);
+ sslContext.engineInit(null, null, null);
+ sslContext.engineGetClientSessionContext().setPersistentCache(
+ FileClientSessionCache.usingDirectory(getCacheDirectory()));
Stopwatch stopwatch = new Stopwatch();
diff --git a/tests/CoreTests/android/core/SSLSocketTest.java b/tests/CoreTests/android/core/SSLSocketTest.java
index 021df80..03905e1 100644
--- a/tests/CoreTests/android/core/SSLSocketTest.java
+++ b/tests/CoreTests/android/core/SSLSocketTest.java
@@ -911,7 +911,8 @@
// Cache size = 2.
FakeClientSessionCache fakeCache = new FakeClientSessionCache();
- context.engineInit(null, null, null, fakeCache, null);
+ context.engineInit(null, null, null);
+ context.engineGetClientSessionContext().setPersistentCache(fakeCache);
SSLSocketFactory socketFactory = context.engineGetSocketFactory();
context.engineGetClientSessionContext().setSessionCacheSize(2);
makeRequests(socketFactory);
@@ -933,7 +934,8 @@
// Cache size = 3.
fakeCache = new FakeClientSessionCache();
- context.engineInit(null, null, null, fakeCache, null);
+ context.engineInit(null, null, null);
+ context.engineGetClientSessionContext().setPersistentCache(fakeCache);
socketFactory = context.engineGetSocketFactory();
context.engineGetClientSessionContext().setSessionCacheSize(3);
makeRequests(socketFactory);
@@ -952,7 +954,8 @@
// Cache size = 4.
fakeCache = new FakeClientSessionCache();
- context.engineInit(null, null, null, fakeCache, null);
+ context.engineInit(null, null, null);
+ context.engineGetClientSessionContext().setPersistentCache(fakeCache);
socketFactory = context.engineGetSocketFactory();
context.engineGetClientSessionContext().setSessionCacheSize(4);
makeRequests(socketFactory);
@@ -1010,7 +1013,8 @@
try {
ClientSessionCacheProxy cacheProxy
= new ClientSessionCacheProxy(fileCache);
- context.engineInit(null, null, null, cacheProxy, null);
+ context.engineInit(null, null, null);
+ context.engineGetClientSessionContext().setPersistentCache(cacheProxy);
SSLSocketFactory socketFactory = context.engineGetSocketFactory();
context.engineGetClientSessionContext().setSessionCacheSize(1);
makeRequests(socketFactory);
@@ -1033,7 +1037,8 @@
// Try again now that file-based cache is populated.
fileCache = FileClientSessionCache.usingDirectory(cacheDir);
cacheProxy = new ClientSessionCacheProxy(fileCache);
- context.engineInit(null, null, null, cacheProxy, null);
+ context.engineInit(null, null, null);
+ context.engineGetClientSessionContext().setPersistentCache(cacheProxy);
socketFactory = context.engineGetSocketFactory();
context.engineGetClientSessionContext().setSessionCacheSize(1);
makeRequests(socketFactory);