Merge "Add matrix component types. Fix potental overflow in script -> java messages."
diff --git a/api/current.xml b/api/current.xml
index 8ff263c..619b257 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -51208,6 +51208,17 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
+<method name="startCommit"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
</interface>
<interface name="SharedPreferences.OnSharedPreferenceChangeListener"
abstract="true"
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index e34bad2..fee95aa 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2878,6 +2878,11 @@
}
}
+ public void startCommit() {
+ // TODO: implement
+ commit();
+ }
+
public boolean commit() {
boolean returnValue;
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 5847216..6ee716a 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -163,14 +163,47 @@
* {@link SharedPreferences} object it is editing. This atomically
* performs the requested modifications, replacing whatever is currently
* in the SharedPreferences.
- *
+ *
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call commit wins.
- *
+ *
+ * <p>If you don't care about the return value and you're
+ * using this from your application's main thread, consider
+ * using {@link #startCommit} instead.
+ *
* @return Returns true if the new values were successfully written
* to persistent storage.
*/
boolean commit();
+
+ /**
+ * Commit your preferences changes back from this Editor to the
+ * {@link SharedPreferences} object it is editing. This atomically
+ * performs the requested modifications, replacing whatever is currently
+ * in the SharedPreferences.
+ *
+ * <p>Note that when two editors are modifying preferences at the same
+ * time, the last one to call commit wins.
+ *
+ * <p>Unlike {@link #commit}, which writes its preferences out
+ * to persistent storage synchronously, {@link #startCommit}
+ * commits its changes to the in-memory
+ * {@link SharedPreferences} immediately but starts an
+ * asynchronous commit to disk and you won't be notified of
+ * any failures. If another editor on this
+ * {@link SharedPreferences} does a regular {@link #commit}
+ * while a {@link #startCommit} is still outstanding, the
+ * {@link #commit} will block until all async commits are
+ * completed as well as the commit itself.
+ *
+ * <p>If you call this from an {@link android.app.Activity},
+ * the base class will wait for any async commits to finish in
+ * its {@link android.app.Activity#onPause}.</p>
+ *
+ * @return Returns true if the new values were successfully written
+ * to persistent storage.
+ */
+ void startCommit();
}
/**
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 97921fe..0068724 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -34,11 +34,19 @@
import java.util.List;
/**
+ * <p>
* SensorManager lets you access the device's {@link android.hardware.Sensor
* sensors}. Get an instance of this class by calling
* {@link android.content.Context#getSystemService(java.lang.String)
* Context.getSystemService()} with the argument
* {@link android.content.Context#SENSOR_SERVICE}.
+ * </p>
+ * <p>
+ * Always make sure to disable sensors you don't need, especially when your
+ * activity is paused. Failing to do so can drain the battery in just a few
+ * hours. Note that the system will <i>not</i> disable sensors automatically when
+ * the screen turns off.
+ * </p>
*
* <pre class="prettyprint">
* public class SensorActivity extends Activity, implements SensorEventListener {
@@ -48,13 +56,22 @@
* public SensorActivity() {
* mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
* mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ * }
+ *
+ * protected void onResume() {
+ * super.onResume();
* mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
* }
*
+ * protected void onPause() {
+ * super.onPause();
+ * mSensorManager.unregisterListener(this);
+ * }
+ *
* public void onAccuracyChanged(Sensor sensor, int accuracy) {
* }
*
- * public abstract void onSensorChanged(SensorEvent event) {
+ * public void onSensorChanged(SensorEvent event) {
* }
* }
* </pre>
diff --git a/core/java/android/provider/Mtp.java b/core/java/android/provider/Mtp.java
index bc764ac..26aa7d8 100644
--- a/core/java/android/provider/Mtp.java
+++ b/core/java/android/provider/Mtp.java
@@ -311,9 +311,12 @@
// Object properties we support
public static final int PROPERTY_STORAGE_ID = 0xDC01;
public static final int PROPERTY_OBJECT_FORMAT = 0xDC02;
+ public static final int PROPERTY_PROTECTION_STATUS = 0xDC03;
public static final int PROPERTY_OBJECT_SIZE = 0xDC04;
public static final int PROPERTY_OBJECT_FILE_NAME = 0xDC07;
+ public static final int PROPERTY_DATE_MODIFIED = 0xDC09;
public static final int PROPERTY_PARENT_OBJECT = 0xDC0B;
+ public static final int PROPERTY_PERSISTENT_UID = 0xDC41;
/**
* Object is not protected. It may be modified and deleted, and its properties
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 32d8123..42e3641 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -53,8 +53,10 @@
/**
* Destroys the hardware rendering context.
+ *
+ * @param full If true, destroys all associated resources.
*/
- abstract void destroy();
+ abstract void destroy(boolean full);
/**
* Initializes the hardware renderer for the specified surface.
@@ -187,7 +189,7 @@
}
/**
- * Checks for OpenGL errors. If an error has occured, {@link #destroy()}
+ * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
* is invoked and the requested flag is turned off. The error code is
* also logged as a warning.
*/
@@ -197,7 +199,7 @@
if (error != EGL10.EGL_SUCCESS) {
// something bad has happened revert to
// normal rendering.
- destroy();
+ destroy(true);
if (error != EGL11.EGL_CONTEXT_LOST) {
// we'll try again if it was context lost
setRequested(false);
@@ -217,13 +219,12 @@
if (mGl != null) {
int err = sEgl.eglGetError();
if (err != EGL10.EGL_SUCCESS) {
- destroy();
+ destroy(true);
setRequested(false);
} else {
- if (mCanvas != null) {
- destroyCanvas();
+ if (mCanvas == null) {
+ mCanvas = createCanvas();
}
- mCanvas = createCanvas();
if (mCanvas != null) {
setEnabled(true);
} else {
@@ -237,11 +238,6 @@
return false;
}
- private void destroyCanvas() {
- mCanvas.destroy();
- mCanvas = null;
- }
-
abstract GLES20Canvas createCanvas();
void initializeEgl() {
@@ -341,16 +337,16 @@
}
@Override
- void destroy() {
+ void destroy(boolean full) {
+ if (full && mCanvas != null) {
+ mCanvas.destroy();
+ mCanvas = null;
+ }
+
if (!isEnabled() || mDestroyed) return;
mDestroyed = true;
- checkCurrent();
- // Destroy the Canvas first in case it needs to use a GL context
- // to perform its cleanup.
- destroyCanvas();
-
sEgl.eglMakeCurrent(sEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
@@ -358,12 +354,6 @@
mEglSurface = null;
mGl = null;
- // mEgl.eglDestroyContext(mEglDisplay, mEglContext);
- // mEglContext = null;
- // mEgl.eglTerminate(mEglDisplay);
- // mEgl = null;
- // mEglDisplay = null;
-
setEnabled(false);
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 5999aba..a91d2bd 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -469,7 +469,9 @@
if (attrs != null &&
(attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
final boolean translucent = attrs.format != PixelFormat.OPAQUE;
- destroyHardwareRenderer();
+ if (mHwRenderer != null) {
+ mHwRenderer.destroy(true);
+ }
mHwRenderer = HardwareRenderer.createGlRenderer(2, translucent);
}
}
@@ -678,7 +680,9 @@
attachInfo.mWindowVisibility = viewVisibility;
host.dispatchWindowVisibilityChanged(viewVisibility);
if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
- destroyHardwareRenderer();
+ if (mHwRenderer != null) {
+ mHwRenderer.destroy(false);
+ }
}
if (viewVisibility == View.GONE) {
// After making a window gone, we will count it as being
@@ -1597,9 +1601,11 @@
mAttachInfo.mRootView = null;
mAttachInfo.mSurface = null;
- destroyHardwareRenderer();
- mHwRenderer = null;
-
+ if (mHwRenderer != null) {
+ mHwRenderer.destroy(true);
+ mHwRenderer = null;
+ }
+
mSurface.release();
if (mInputChannel != null) {
@@ -1624,12 +1630,6 @@
}
}
- private void destroyHardwareRenderer() {
- if (mHwRenderer != null) {
- mHwRenderer.destroy();
- }
- }
-
void updateConfiguration(Configuration config, boolean force) {
if (DEBUG_CONFIGURATION) Log.v(TAG,
"Applying new config to window "
diff --git a/core/res/res/values-rm/donottranslate-cldr.xml b/core/res/res/values-rm/donottranslate-cldr.xml
new file mode 100644
index 0000000..4b9f9db
--- /dev/null
+++ b/core/res/res/values-rm/donottranslate-cldr.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">schaner</string>
+ <string name="month_long_standalone_february">favrer</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">avrigl</string>
+ <string name="month_long_standalone_may">matg</string>
+ <string name="month_long_standalone_june">zercladur</string>
+ <string name="month_long_standalone_july">fanadur</string>
+ <string name="month_long_standalone_august">avust</string>
+ <string name="month_long_standalone_september">settember</string>
+ <string name="month_long_standalone_october">october</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">schaner</string>
+ <string name="month_long_february">favrer</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">avrigl</string>
+ <string name="month_long_may">matg</string>
+ <string name="month_long_june">zercladur</string>
+ <string name="month_long_july">fanadur</string>
+ <string name="month_long_august">avust</string>
+ <string name="month_long_september">settember</string>
+ <string name="month_long_october">october</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">schan.</string>
+ <string name="month_medium_february">favr.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">avr.</string>
+ <string name="month_medium_may">matg</string>
+ <string name="month_medium_june">zercl.</string>
+ <string name="month_medium_july">fan.</string>
+ <string name="month_medium_august">avust</string>
+ <string name="month_medium_september">sett.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">S</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">Z</string>
+ <string name="month_shortest_july">F</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="sunday">dumengia</string>
+ <string name="monday">glindesdi</string>
+ <string name="tuesday">mardi</string>
+ <string name="wednesday">mesemna</string>
+ <string name="thursday">gievgia</string>
+ <string name="friday">venderdi</string>
+ <string name="saturday">sonda</string>
+
+ <string name="day_of_week_long_sunday">dumengia</string>
+ <string name="day_of_week_long_monday">glindesdi</string>
+ <string name="day_of_week_long_tuesday">mardi</string>
+ <string name="day_of_week_long_wednesday">mesemna</string>
+ <string name="day_of_week_long_thursday">gievgia</string>
+ <string name="day_of_week_long_friday">venderdi</string>
+ <string name="day_of_week_long_saturday">sonda</string>
+
+ <string name="day_of_week_medium_sunday">du</string>
+ <string name="day_of_week_medium_monday">gli</string>
+ <string name="day_of_week_medium_tuesday">ma</string>
+ <string name="day_of_week_medium_wednesday">me</string>
+ <string name="day_of_week_medium_thursday">gie</string>
+ <string name="day_of_week_medium_friday">ve</string>
+ <string name="day_of_week_medium_saturday">so</string>
+
+ <string name="day_of_week_short_sunday">du</string>
+ <string name="day_of_week_short_monday">gli</string>
+ <string name="day_of_week_short_tuesday">ma</string>
+ <string name="day_of_week_short_wednesday">me</string>
+ <string name="day_of_week_short_thursday">gie</string>
+ <string name="day_of_week_short_friday">ve</string>
+ <string name="day_of_week_short_saturday">so</string>
+
+ <string name="day_of_week_shorter_sunday">D</string>
+ <string name="day_of_week_shorter_monday">G</string>
+ <string name="day_of_week_shorter_tuesday">M</string>
+ <string name="day_of_week_shorter_wednesday">M</string>
+ <string name="day_of_week_shorter_thursday">G</string>
+ <string name="day_of_week_shorter_friday">V</string>
+ <string name="day_of_week_shorter_saturday">S</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">G</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">G</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="yesterday">ier</string>
+ <string name="today">oz</string>
+ <string name="tomorrow">damaun</string>
+
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="full_date_month_first">d. MMMM y</string>
+ <string name="full_date_day_first">d. MMMM y</string>
+ <string name="medium_date_month_first">d. MMM y</string>
+ <string name="medium_date_day_first">d. MMM y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="status_bar_time_format">HH:mm</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%3$s, %1$s</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="short_format_month">%b</string>
+</resources>
diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h
index 53205bb..a3f094c 100644
--- a/include/media/EffectPresetReverbApi.h
+++ b/include/media/EffectPresetReverbApi.h
@@ -43,7 +43,8 @@
REVERB_PRESET_LARGEROOM,
REVERB_PRESET_MEDIUMHALL,
REVERB_PRESET_LARGEHALL,
- REVERB_PRESET_PLATE
+ REVERB_PRESET_PLATE,
+ REVERB_PRESET_LAST = REVERB_PRESET_PLATE
} t_reverb_presets;
#if __cplusplus
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 88cce46..7e0d390 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -66,14 +66,6 @@
private final MediaScanner mMediaScanner;
- // MTP property codes
- private static final int MTP_PROPERTY_STORAGE_ID = 0xDC01;
- private static final int MTP_PROPERTY_OBJECT_FORMAT = 0xDC02;
- private static final int MTP_PROPERTY_OBJECT_SIZE = 0xDC04;
- private static final int MTP_PROPERTY_OBJECT_FILE_NAME = 0xDC07;
- private static final int MTP_PROPERTY_DATE_MODIFIED = 0xDC09;
- private static final int MTP_PROPERTY_PARENT_OBJECT = 0xDC0B;
-
// MTP response codes
private static final int MTP_RESPONSE_OK = 0x2001;
private static final int MTP_RESPONSE_GENERAL_ERROR = 0x2002;
@@ -271,25 +263,36 @@
boolean isString = false;
switch (property) {
- case MTP_PROPERTY_STORAGE_ID:
+ case Mtp.Object.PROPERTY_STORAGE_ID:
outIntValue[0] = mStorageID;
return MTP_RESPONSE_OK;
- case MTP_PROPERTY_OBJECT_FORMAT:
+ case Mtp.Object.PROPERTY_OBJECT_FORMAT:
column = MtpObjects.ObjectColumns.FORMAT;
break;
- case MTP_PROPERTY_OBJECT_SIZE:
+ case Mtp.Object.PROPERTY_PROTECTION_STATUS:
+ // protection status is always 0
+ outIntValue[0] = 0;
+ return MTP_RESPONSE_OK;
+ case Mtp.Object.PROPERTY_OBJECT_SIZE:
column = MtpObjects.ObjectColumns.SIZE;
break;
- case MTP_PROPERTY_OBJECT_FILE_NAME:
+ case Mtp.Object.PROPERTY_OBJECT_FILE_NAME:
column = MtpObjects.ObjectColumns.DATA;
isString = true;
break;
- case MTP_PROPERTY_DATE_MODIFIED:
+ case Mtp.Object.PROPERTY_DATE_MODIFIED:
column = MtpObjects.ObjectColumns.DATE_MODIFIED;
break;
- case MTP_PROPERTY_PARENT_OBJECT:
+ case Mtp.Object.PROPERTY_PARENT_OBJECT:
column = MtpObjects.ObjectColumns.PARENT;
break;
+ case Mtp.Object.PROPERTY_PERSISTENT_UID:
+ // PUID is concatenation of storageID and object handle
+ long puid = mStorageID;
+ puid <<= 32;
+ puid += handle;
+ outIntValue[0] = puid;
+ return MTP_RESPONSE_OK;
default:
return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
}
@@ -305,7 +308,7 @@
String value = c.getString(1);
int start = 0;
- if (property == MTP_PROPERTY_OBJECT_FILE_NAME) {
+ if (property == Mtp.Object.PROPERTY_OBJECT_FILE_NAME) {
// extract name from full path
int lastSlash = value.lastIndexOf('/');
if (lastSlash >= 0) {
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index bf83172..4ef3a9f 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -29,6 +29,7 @@
#include "MtpDatabase.h"
#include "MtpDataPacket.h"
+#include "MtpProperty.h"
#include "MtpUtils.h"
#include "mtp.h"
@@ -45,6 +46,7 @@
static jmethodID method_getSupportedObjectProperties;
static jmethodID method_getSupportedDeviceProperties;
static jmethodID method_getObjectProperty;
+static jmethodID method_setObjectProperty;
static jmethodID method_getObjectInfo;
static jmethodID method_getObjectFilePath;
static jmethodID method_deleteFile;
@@ -98,10 +100,22 @@
virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
virtual MtpDevicePropertyList* getSupportedDeviceProperties();
- virtual MtpResponseCode getObjectProperty(MtpObjectHandle handle,
+ virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet);
+ virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
+ MtpObjectProperty property,
+ MtpDataPacket& packet);
+
+ virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
+ MtpDataPacket& packet);
+
+ virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
+ MtpDataPacket& packet);
+
+ virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
+
virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet);
@@ -116,6 +130,11 @@
virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
MtpObjectHandleList* references);
+
+ virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
+ MtpObjectFormat format);
+
+ virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
};
// ----------------------------------------------------------------------------
@@ -292,7 +311,7 @@
return list;
}
-MtpResponseCode MyMtpDatabase::getObjectProperty(MtpObjectHandle handle,
+MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) {
int type;
@@ -310,6 +329,15 @@
jlong longValue = longValues[0];
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
+ // special case MTP_PROPERTY_DATE_MODIFIED, which is a string to MTP
+ // but stored internally as a uint64
+ if (property == MTP_PROPERTY_DATE_MODIFIED) {
+ char date[20];
+ formatDateTime(longValue, date, sizeof(date));
+ packet.putString(date);
+ return MTP_RESPONSE_OK;
+ }
+
switch (type) {
case MTP_TYPE_INT8:
packet.putInt8(longValue);
@@ -335,6 +363,12 @@
case MTP_TYPE_UINT64:
packet.putUInt64(longValue);
break;
+ case MTP_TYPE_INT128:
+ packet.putInt128(longValue);
+ break;
+ case MTP_TYPE_UINT128:
+ packet.putInt128(longValue);
+ break;
case MTP_TYPE_STR:
{
jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
@@ -351,6 +385,26 @@
return MTP_RESPONSE_OK;
}
+MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
+ MtpObjectProperty property,
+ MtpDataPacket& packet) {
+ return -1;
+}
+
+MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
+ MtpDataPacket& packet) {
+ return -1;
+}
+
+MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
+ MtpDataPacket& packet) {
+ return -1;
+}
+
+MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
+ return -1;
+}
+
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet) {
char date[20];
@@ -372,9 +426,10 @@
uint64_t modified = longValues[1];
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
- int associationType = (format == MTP_FORMAT_ASSOCIATION ?
- MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
- MTP_ASSOCIATION_TYPE_UNDEFINED);
+// int associationType = (format == MTP_FORMAT_ASSOCIATION ?
+// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
+// MTP_ASSOCIATION_TYPE_UNDEFINED);
+ int associationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
packet.putUInt32(storageID);
packet.putUInt16(format);
@@ -497,6 +552,37 @@
return result;
}
+MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
+ MtpObjectFormat format) {
+ MtpProperty* result = NULL;
+ switch (property) {
+ case MTP_PROPERTY_OBJECT_FORMAT:
+ case MTP_PROPERTY_PROTECTION_STATUS:
+ result = new MtpProperty(property, MTP_TYPE_UINT16);
+ break;
+ case MTP_PROPERTY_STORAGE_ID:
+ case MTP_PROPERTY_PARENT_OBJECT:
+ result = new MtpProperty(property, MTP_TYPE_UINT32);
+ break;
+ case MTP_PROPERTY_OBJECT_SIZE:
+ result = new MtpProperty(property, MTP_TYPE_UINT64);
+ break;
+ case MTP_PROPERTY_PERSISTENT_UID:
+ result = new MtpProperty(property, MTP_TYPE_UINT128);
+ break;
+ case MTP_PROPERTY_OBJECT_FILE_NAME:
+ case MTP_PROPERTY_DATE_MODIFIED:
+ result = new MtpProperty(property, MTP_TYPE_STR);
+ break;
+ }
+
+ return result;
+}
+
+MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
+ return NULL;
+}
+
#endif // HAVE_ANDROID_OS
// ----------------------------------------------------------------------------
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 798271e..d856eb4 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "Bundle"
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <cutils/log.h>
#include <assert.h>
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 2043e44..03f1409 100755
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "Reverb"
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <cutils/log.h>
#include <assert.h>
@@ -61,42 +61,81 @@
/* Preset definitions */
/* */
/************************************************************************************/
-LVM_UINT16 RevPreset_Level[] = { 32, 32, 32, 32, 32, 32, 32, 32, 32, 32};
-LVM_UINT16 RevPreset_LPF[] = {1298, 1000, 5012, 3542, 3400, 23999, 2536, 1000, 1000, 1000};
-LVM_UINT16 RevPreset_HPF[] = { 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
-LVM_UINT16 RevPreset_T60[] = {1490, 500, 2310, 4230, 3920, 2910, 7000, 1490, 1490, 170};
-LVM_UINT16 RevPreset_Density[] = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
-LVM_UINT16 RevPreset_Damping[] = { 54, 10, 64, 59, 70, 100, 33, 54, 21, 10};
-LVM_UINT16 RevPreset_RoomSize[] = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
-/************************************************************************************/
-/* */
-/* Preset definitions */
-/* */
-/************************************************************************************/
-#define REV_PRESET_BATHROOM 0
-#define REV_PRESET_LIVINGROOM 1
-#define REV_PRESET_STONEROOM 2
-#define REV_PRESET_AUDITORIUM 3
-#define REV_PRESET_CONCERTHALL 4
-#define REV_PRESET_CAVE 5
-#define REV_PRESET_ARENA 6
-#define REV_PRESET_FOREST 7
-#define REV_PRESET_MOUNTAINS 8
-#define REV_PRESET_PADDEDCELL 9
+const static t_reverb_settings sReverbPresets[] = {
+ // REVERB_PRESET_NONE: values are unused
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ // REVERB_PRESET_SMALLROOM
+ {-1000, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000},
+ // REVERB_PRESET_MEDIUMROOM
+ {-1000, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000},
+ // REVERB_PRESET_LARGEROOM
+ {-1000, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000},
+ // REVERB_PRESET_MEDIUMHALL
+ {-1000, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000},
+ // REVERB_PRESET_LARGEHALL
+ {-1000, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000},
+ // REVERB_PRESET_PLATE
+ {-1000, -200, 1300, 900, 0, 2, 0, 10, 1000, 750},
+};
-// NXP SW Reverb UUID
-const effect_descriptor_t gReverbDescriptor = {
+
+// NXP SW auxiliary environmental reverb
+const effect_descriptor_t gAuxEnvReverbDescriptor = {
{ 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } },
{ 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
EFFECT_API_VERSION,
- (EFFECT_FLAG_TYPE_AUXILIARY | EFFECT_FLAG_INSERT_LAST),
+ EFFECT_FLAG_TYPE_AUXILIARY,
0, // TODO
1,
- "Reverb",
+ "Auxiliary Environmental Reverb",
"NXP Software Ltd.",
};
+// NXP SW insert environmental reverb
+static const effect_descriptor_t gInsertEnvReverbDescriptor = {
+ {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
+ {0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ EFFECT_API_VERSION,
+ EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
+ 0, // TODO
+ 1,
+ "Insert Environmental Reverb",
+ "NXP Software Ltd.",
+};
+
+// NXP SW auxiliary preset reverb
+static const effect_descriptor_t gAuxPresetReverbDescriptor = {
+ {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ {0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ EFFECT_API_VERSION,
+ EFFECT_FLAG_TYPE_AUXILIARY,
+ 0, // TODO
+ 1,
+ "Auxiliary Preset Reverb",
+ "NXP Software Ltd.",
+};
+
+// NXP SW insert preset reverb
+static const effect_descriptor_t gInsertPresetReverbDescriptor = {
+ {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ {0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+ EFFECT_API_VERSION,
+ EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
+ 0, // TODO
+ 1,
+ "Insert Preset Reverb",
+ "NXP Software Ltd.",
+};
+
+// gDescriptors contains pointers to all defined effect descriptor in this library
+static const effect_descriptor_t * const gDescriptors[] = {
+ &gAuxEnvReverbDescriptor,
+ &gInsertEnvReverbDescriptor,
+ &gAuxPresetReverbDescriptor,
+ &gInsertPresetReverbDescriptor
+};
+
struct ReverbContext{
const struct effect_interface_s *itfe;
effect_config_t config;
@@ -114,8 +153,14 @@
FILE *PcmOutPtr;
#endif
LVM_Fs_en SampleRate;
+ bool auxiliary;
+ bool preset;
+ uint16_t curPreset;
+ uint16_t nextPreset;
};
+#define REVERB_DEFAULT_PRESET REVERB_PRESET_MEDIUMROOM
+
//--- local function prototypes
int Reverb_init (ReverbContext *pContext);
void Reverb_free (ReverbContext *pContext);
@@ -125,11 +170,12 @@
void *pParam,
size_t *pValueSize,
void *pValue);
+int Reverb_LoadPreset (ReverbContext *pContext);
/* Effect Library Interface Implementation */
extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects){
LOGV("\n\tEffectQueryNumberEffects start");
- *pNumEffects = 1;
+ *pNumEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
LOGV("\tEffectQueryNumberEffects creating %d effects", *pNumEffects);
LOGV("\tEffectQueryNumberEffects end\n");
return 0;
@@ -142,11 +188,11 @@
LOGV("\tLVM_ERROR : EffectQueryEffect was passed NULL pointer");
return -EINVAL;
}
- if (index > 0){
+ if (index >= sizeof(gDescriptors) / sizeof(const effect_descriptor_t *)) {
LOGV("\tLVM_ERROR : EffectQueryEffect index out of range %d", index);
return -ENOENT;
}
- memcpy(pDescriptor, &gReverbDescriptor, sizeof(effect_descriptor_t));
+ memcpy(pDescriptor, gDescriptors[index], sizeof(effect_descriptor_t));
LOGV("\tEffectQueryEffect end\n");
return 0;
} /* end EffectQueryEffect */
@@ -157,6 +203,8 @@
effect_interface_t *pInterface){
int ret;
int i;
+ int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
+ const effect_descriptor_t *desc;
LOGV("\t\nEffectCreate start");
@@ -165,9 +213,16 @@
return -EINVAL;
}
- if (memcmp(uuid, &gReverbDescriptor.uuid, sizeof(effect_uuid_t)) != 0){
- LOGV("\tLVM_ERROR : EffectCreate() invalid UUID");
- return -EINVAL;
+ for (i = 0; i < length; i++) {
+ desc = gDescriptors[i];
+ if (memcmp(uuid, &desc->uuid, sizeof(effect_uuid_t))
+ == 0) {
+ break;
+ }
+ }
+
+ if (i == length) {
+ return -ENOENT;
}
ReverbContext *pContext = new ReverbContext;
@@ -175,6 +230,19 @@
pContext->itfe = &gReverbInterface;
pContext->hInstance = NULL;
+ pContext->auxiliary = false;
+ if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY){
+ pContext->auxiliary = true;
+ }
+
+ pContext->preset = false;
+ if (memcmp(&desc->type, SL_IID_PRESETREVERB, sizeof(effect_uuid_t)) == 0) {
+ pContext->preset = true;
+ // force reloading preset at first call to process()
+ pContext->curPreset = REVERB_PRESET_LAST + 1;
+ pContext->nextPreset = REVERB_DEFAULT_PRESET;
+ }
+
LOGV("\tEffectCreate - Calling Reverb_init");
ret = Reverb_init(pContext);
@@ -288,6 +356,14 @@
return;
}
+
+static inline int16_t clamp16(int32_t sample)
+{
+ if ((sample>>15) ^ (sample>>31))
+ sample = 0x7FFF ^ (sample>>31);
+ return sample;
+}
+
//----------------------------------------------------------------------------
// process()
//----------------------------------------------------------------------------
@@ -344,6 +420,9 @@
fflush(pContext->PcmInPtr);
#endif
+ if (pContext->preset && pContext->nextPreset != pContext->curPreset) {
+ Reverb_LoadPreset(pContext);
+ }
// Convert to Input 32 bits
for(int i=0; i<frameCount*samplesPerFrame; i++){
InFrames32[i] = (LVM_INT32)pIn[i]<<8;
@@ -359,18 +438,28 @@
//frameCount, pContext->config.inputCfg.channels, CHANNEL_MONO,
//pContext->config.outputCfg.channels, CHANNEL_STEREO);
+ if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
+ memset(OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2);
+ } else {
/* Process the samples */
LvmStatus = LVREV_Process(pContext->hInstance, /* Instance handle */
InFrames32, /* Input buffer */
OutFrames32, /* Output buffer */
frameCount); /* Number of samples to read */
+ }
+
+ if (!pContext->auxiliary) {
+ for (int i=0; i<frameCount*2; i++){
+ OutFrames32[i] += InFrames32[i];
+ }
+ }
LVM_ERROR_CHECK(LvmStatus, "LVREV_Process", "process")
if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
// Convert to 16 bits
for(int i=0; i<frameCount*2; i++){ // Always stereo
- OutFrames16[i] = (LVM_INT16)(OutFrames32[i]>>8);
+ OutFrames16[i] = clamp16(OutFrames32[i]>>8);
}
#ifdef LVM_PCM
@@ -382,7 +471,7 @@
if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
//LOGV("\tBuffer access is ACCUMULATE");
for (int i=0; i<frameCount*2; i++){
- pOut[i] += OutFrames16[i];
+ pOut[i] = clamp16((int32_t)pOut[i] + (int32_t)OutFrames16[i]);
}
}else{
//LOGV("\tBuffer access is WRITE");
@@ -462,6 +551,8 @@
CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
+ CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == CHANNEL_MONO) ||
+ ((!pContext->auxiliary) && pConfig->inputCfg.channels == CHANNEL_STEREO));
CHECK_ARG(pConfig->outputCfg.channels == CHANNEL_STEREO);
CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
|| pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
@@ -540,18 +631,8 @@
int Reverb_init(ReverbContext *pContext){
int status;
- int channel_mode;
- LOGV("\tReverb_init start %d", gReverbDescriptor.flags);
-
- if((gReverbDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT){
- LOGV("\tReverb_init EFFECT_FLAG_TYPE_INSERT");
- channel_mode = CHANNEL_STEREO;
- }
- if((gReverbDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY ){
- LOGV("\tReverb_init EFFECT_FLAG_TYPE_AUXILIARY");
- channel_mode = CHANNEL_MONO;
- }
+ LOGV("\tReverb_init start");
CHECK_ARG(pContext != NULL);
@@ -560,7 +641,12 @@
}
pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
- pContext->config.inputCfg.channels = channel_mode;
+ if (pContext->auxiliary) {
+ pContext->config.inputCfg.channels = CHANNEL_MONO;
+ } else {
+ pContext->config.inputCfg.channels = CHANNEL_STEREO;
+ }
+
pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15;
pContext->config.inputCfg.samplingRate = 44100;
pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
@@ -653,11 +739,11 @@
/* Reverb parameters */
params.Level = 0;
params.LPF = 23999;
- params.HPF = RevPreset_HPF[REV_PRESET_MOUNTAINS];
- params.T60 = RevPreset_T60[REV_PRESET_MOUNTAINS];
- params.Density = RevPreset_Density[REV_PRESET_MOUNTAINS];
- params.Damping = RevPreset_Damping[REV_PRESET_MOUNTAINS];
- params.RoomSize = RevPreset_RoomSize[REV_PRESET_MOUNTAINS];
+ params.HPF = 50;
+ params.T60 = 1490;
+ params.Density = 100;
+ params.Damping = 21;
+ params.RoomSize = 100;
/* Saved strength is used to return the exact strength that was used in the set to the get
* because we map the original strength range of 0:1000 to 1:15, and this will avoid
@@ -1294,6 +1380,44 @@
}
//----------------------------------------------------------------------------
+// Reverb_LoadPreset()
+//----------------------------------------------------------------------------
+// Purpose:
+// Load a the next preset
+//
+// Inputs:
+// pContext - handle to instance data
+//
+// Outputs:
+//
+// Side Effects:
+//
+//----------------------------------------------------------------------------
+int Reverb_LoadPreset(ReverbContext *pContext)
+{
+ //TODO: add reflections delay, level and reverb delay when early reflections are
+ // implemented
+ pContext->curPreset = pContext->nextPreset;
+
+ if (pContext->curPreset != REVERB_PRESET_NONE) {
+ const t_reverb_settings *preset = &sReverbPresets[pContext->curPreset];
+ ReverbSetRoomLevel(pContext, preset->roomLevel);
+ ReverbSetRoomHfLevel(pContext, preset->roomHFLevel);
+ ReverbSetDecayTime(pContext, preset->decayTime);
+ ReverbSetDecayHfRatio(pContext, preset->decayHFRatio);
+ //reflectionsLevel
+ //reflectionsDelay
+ ReverbSetReverbLevel(pContext, preset->reverbLevel);
+ // reverbDelay
+ ReverbSetDiffusion(pContext, preset->diffusion);
+ ReverbSetDensity(pContext, preset->density);
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
// Reverb_getParameter()
//----------------------------------------------------------------------------
// Purpose:
@@ -1325,6 +1449,15 @@
t_reverb_settings *pProperties;
//LOGV("\tReverb_getParameter start");
+ if (pContext->preset) {
+ if (param != REVERB_PARAM_PRESET || *pValueSize < sizeof(uint16_t)) {
+ return -EINVAL;
+ }
+
+ *(uint16_t *)pValue = pContext->nextPreset;
+ LOGV("get REVERB_PARAM_PRESET, preset %d", pContext->nextPreset);
+ return 0;
+ }
switch (param){
case REVERB_PARAM_ROOM_LEVEL:
@@ -1531,6 +1664,18 @@
int32_t param = *pParamTemp++;
//LOGV("\tReverb_setParameter start");
+ if (pContext->preset) {
+ if (param != REVERB_PARAM_PRESET) {
+ return -EINVAL;
+ }
+
+ uint16_t preset = *(uint16_t *)pValue;
+ LOGV("set REVERB_PARAM_PRESET, preset %d", preset);
+ if (preset > REVERB_PRESET_LAST) {
+ return -EINVAL;
+ }
+ pContext->nextPreset = preset;
+ }
switch (param){
case REVERB_PARAM_PROPERTIES:
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index e167afa..1ccfa03 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -461,27 +461,34 @@
return;
}
+ bool eos;
+ size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);
+
size_t lowWatermark = 400000;
size_t highWatermark = 1000000;
- off_t size;
- if (mDurationUs >= 0 && mCachedSource->getSize(&size) == OK) {
- int64_t bitrate = size * 8000000ll / mDurationUs; // in bits/sec
+ if (eos) {
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
+ } else {
+ off_t size;
+ if (mDurationUs >= 0 && mCachedSource->getSize(&size) == OK) {
+ int64_t bitrate = size * 8000000ll / mDurationUs; // in bits/sec
- size_t cachedSize = mCachedSource->cachedSize();
- int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
+ size_t cachedSize = mCachedSource->cachedSize();
+ int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
- double percentage = (double)cachedDurationUs / mDurationUs;
+ int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
+ if (percentage > 100) {
+ percentage = 100;
+ }
- notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage * 100.0);
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
- lowWatermark = 2 * bitrate / 8; // 2 secs
- highWatermark = 10 * bitrate / 8; // 10 secs
+ lowWatermark = 2 * bitrate / 8; // 2 secs
+ highWatermark = 10 * bitrate / 8; // 10 secs
+ }
}
- bool eos;
- size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);
-
if ((mFlags & PLAYING) && !eos && (cachedDataRemaining < lowWatermark)) {
LOGI("cache is running low (< %d) , pausing.", lowWatermark);
mFlags |= CACHE_UNDERRUN;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index ca0c68c..da340f7 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -142,11 +142,22 @@
mSize = size;
if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) {
+ free(mData);
+ mData = NULL;
+
return false;
}
- if (header.flags & 0x80) {
+ if (header.version_major == 4) {
+ if (!removeUnsynchronizationV2_4()) {
+ free(mData);
+ mData = NULL;
+
+ return false;
+ }
+ } else if (header.flags & 0x80) {
LOGV("removing unsynchronization");
+
removeUnsynchronization();
}
@@ -243,6 +254,74 @@
}
}
+static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
+ for (size_t i = 0; i < 4; ++i) {
+ dst[3 - i] = (x & 0x7f);
+ x >>= 7;
+ }
+}
+
+bool ID3::removeUnsynchronizationV2_4() {
+ size_t oldSize = mSize;
+
+ size_t offset = 0;
+ while (offset + 10 <= mSize) {
+ if (!memcmp(&mData[offset], "\0\0\0\0", 4)) {
+ break;
+ }
+
+ size_t dataSize;
+ if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) {
+ return false;
+ }
+
+ if (offset + dataSize + 10 > mSize) {
+ return false;
+ }
+
+ uint16_t flags = U16_AT(&mData[offset + 8]);
+ uint16_t prevFlags = flags;
+
+ if (flags & 1) {
+ // Strip data length indicator
+
+ memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14);
+ mSize -= 4;
+ dataSize -= 4;
+
+ flags &= ~1;
+ }
+
+ if (flags & 2) {
+ // Unsynchronization added.
+
+ for (size_t i = 0; i + 1 < dataSize; ++i) {
+ if (mData[offset + 10 + i] == 0xff
+ && mData[offset + 11 + i] == 0x00) {
+ memmove(&mData[offset + 11 + i], &mData[offset + 12 + i],
+ mSize - offset - 12 - i);
+ --mSize;
+ --dataSize;
+ }
+ }
+
+ flags &= ~2;
+ }
+
+ if (flags != prevFlags) {
+ WriteSyncsafeInteger(&mData[offset + 4], dataSize);
+ mData[offset + 8] = flags >> 8;
+ mData[offset + 9] = flags & 0xff;
+ }
+
+ offset += 10 + dataSize;
+ }
+
+ memset(&mData[mSize], 0, oldSize - mSize);
+
+ return true;
+}
+
ID3::Iterator::Iterator(const ID3 &parent, const char *id)
: mParent(parent),
mID(NULL),
@@ -529,10 +608,11 @@
uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]);
- if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000e))
+ if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c))
|| (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) {
- // Compression, Encryption or per-Frame unsynchronization
- // are not supported at this time.
+ // Compression or encryption are not supported at this time.
+ // Per-frame unsynchronization and data-length indicator
+ // have already been taken care of.
LOGV("Skipping unsupported frame (compression, encryption "
"or per-frame unsynchronization flagged");
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index c6b1a8b..7ddbb41 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -80,6 +80,7 @@
bool parseV1(const sp<DataSource> &source);
bool parseV2(const sp<DataSource> &source);
void removeUnsynchronization();
+ bool removeUnsynchronizationV2_4();
static bool ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x);
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 27dc796..ec78ff0 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -242,6 +242,16 @@
putUInt32(value[3]);
}
+void MtpDataPacket::putInt128(int64_t value) {
+ putInt64(value);
+ putInt64(value < 0 ? -1 : 0);
+}
+
+void MtpDataPacket::putUInt128(uint64_t value) {
+ putUInt64(value);
+ putUInt64(0);
+}
+
void MtpDataPacket::putAInt8(const int8_t* values, int count) {
putUInt32(count);
for (int i = 0; i < count; i++)
@@ -363,7 +373,7 @@
int MtpDataPacket::write(int fd) {
MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
-
+ dump();
// send header separately from data
int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
if (ret == MTP_CONTAINER_HEADER_SIZE)
diff --git a/media/mtp/MtpDataPacket.h b/media/mtp/MtpDataPacket.h
index 1467aab..fab6a07 100644
--- a/media/mtp/MtpDataPacket.h
+++ b/media/mtp/MtpDataPacket.h
@@ -69,6 +69,8 @@
void putUInt64(uint64_t value);
void putInt128(const int128_t& value);
void putUInt128(const uint128_t& value);
+ void putInt128(int64_t value);
+ void putUInt128(uint64_t value);
void putAInt8(const int8_t* values, int count);
void putAUInt8(const uint8_t* values, int count);
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index 17823df..899b34a 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -22,6 +22,7 @@
namespace android {
class MtpDataPacket;
+class MtpProperty;
class MtpDatabase {
public:
@@ -58,10 +59,22 @@
virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format) = 0;
virtual MtpDevicePropertyList* getSupportedDeviceProperties() = 0;
- virtual MtpResponseCode getObjectProperty(MtpObjectHandle handle,
+ virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) = 0;
+ virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
+ MtpObjectProperty property,
+ MtpDataPacket& packet) = 0;
+
+ virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
+ MtpDataPacket& packet) = 0;
+
+ virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
+ MtpDataPacket& packet) = 0;
+
+ virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property) = 0;
+
virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet) = 0;
@@ -76,6 +89,10 @@
virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
MtpObjectHandleList* references) = 0;
+ virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
+ MtpObjectFormat format) = 0;
+
+ virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property) = 0;
};
}; // namespace android
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 30abfb8..1e64e4f 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -56,17 +56,17 @@
// MTP_OPERATION_SET_OBJECT_PROTECTION,
// MTP_OPERATION_POWER_DOWN,
// MTP_OPERATION_GET_DEVICE_PROP_DESC,
-// MTP_OPERATION_GET_DEVICE_PROP_VALUE,
-// MTP_OPERATION_SET_DEVICE_PROP_VALUE,
-// MTP_OPERATION_RESET_DEVICE_PROP_VALUE,
+ MTP_OPERATION_GET_DEVICE_PROP_VALUE,
+ MTP_OPERATION_SET_DEVICE_PROP_VALUE,
+ MTP_OPERATION_RESET_DEVICE_PROP_VALUE,
// MTP_OPERATION_TERMINATE_OPEN_CAPTURE,
// MTP_OPERATION_MOVE_OBJECT,
// MTP_OPERATION_COPY_OBJECT,
// MTP_OPERATION_GET_PARTIAL_OBJECT,
// MTP_OPERATION_INITIATE_OPEN_CAPTURE,
MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED,
-// MTP_OPERATION_GET_OBJECT_PROP_DESC,
- MTP_OPERATION_GET_OBJECT_PROP_VALUE,
+ MTP_OPERATION_GET_OBJECT_PROP_DESC,
+// MTP_OPERATION_GET_OBJECT_PROP_VALUE,
// MTP_OPERATION_SET_OBJECT_PROP_VALUE,
MTP_OPERATION_GET_OBJECT_REFERENCES,
MTP_OPERATION_SET_OBJECT_REFERENCES,
@@ -91,7 +91,6 @@
mSendObjectFormat(0),
mSendObjectFileSize(0)
{
- initObjectProperties();
}
MtpServer::~MtpServer() {
@@ -136,7 +135,9 @@
// FIXME need to generalize this
bool dataIn = (operation == MTP_OPERATION_SEND_OBJECT_INFO
- || operation == MTP_OPERATION_SET_OBJECT_REFERENCES);
+ || operation == MTP_OPERATION_SET_OBJECT_REFERENCES
+ || operation == MTP_OPERATION_SET_OBJECT_PROP_VALUE
+ || operation == MTP_OPERATION_SET_DEVICE_PROP_VALUE);
if (dataIn) {
int ret = mData.read(fd);
if (ret < 0) {
@@ -158,7 +159,6 @@
mData.setOperationCode(operation);
mData.setTransactionID(transaction);
LOGV("sending data:");
- mData.dump();
ret = mData.write(fd);
if (ret < 0) {
LOGE("request write returned %d, errno: %d", ret, errno);
@@ -187,24 +187,6 @@
}
}
-MtpProperty* MtpServer::getObjectProperty(MtpPropertyCode propCode) {
- for (int i = 0; i < mObjectProperties.size(); i++) {
- MtpProperty* property = mObjectProperties[i];
- if (property->getPropertyCode() == propCode)
- return property;
- }
- return NULL;
-}
-
-MtpProperty* MtpServer::getDeviceProperty(MtpPropertyCode propCode) {
- for (int i = 0; i < mDeviceProperties.size(); i++) {
- MtpProperty* property = mDeviceProperties[i];
- if (property->getPropertyCode() == propCode)
- return property;
- }
- return NULL;
-}
-
void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
if (mSessionOpen) {
LOGD("sendObjectAdded %d\n", handle);
@@ -227,14 +209,6 @@
}
}
-void MtpServer::initObjectProperties() {
- mObjectProperties.push(new MtpProperty(MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32));
- mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16));
- mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64));
- mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR));
- mObjectProperties.push(new MtpProperty(MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32));
-}
-
bool MtpServer::handleRequest() {
MtpOperationCode operation = mRequest.getOperationCode();
MtpResponseCode response;
@@ -281,6 +255,18 @@
case MTP_OPERATION_GET_OBJECT_PROP_VALUE:
response = doGetObjectPropValue();
break;
+ case MTP_OPERATION_SET_OBJECT_PROP_VALUE:
+ response = doSetObjectPropValue();
+ break;
+ case MTP_OPERATION_GET_DEVICE_PROP_VALUE:
+ response = doGetDevicePropValue();
+ break;
+ case MTP_OPERATION_SET_DEVICE_PROP_VALUE:
+ response = doSetDevicePropValue();
+ break;
+ case MTP_OPERATION_RESET_DEVICE_PROP_VALUE:
+ response = doResetDevicePropValue();
+ break;
case MTP_OPERATION_GET_OBJECT_INFO:
response = doGetObjectInfo();
break;
@@ -456,13 +442,15 @@
if (!mSessionOpen)
return MTP_RESPONSE_SESSION_NOT_OPEN;
MtpStorageID handle = mRequest.getParameter(1);
+
+ // FIXME - check for invalid object handle
MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle);
- if (!handles) {
+ if (handles) {
+ mData.putAUInt32(handles);
+ delete handles;
+ } else {
mData.putEmptyArray();
- return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
}
- mData.putAUInt32(handles);
- delete handles;
return MTP_RESPONSE_OK;
}
@@ -479,8 +467,43 @@
MtpResponseCode MtpServer::doGetObjectPropValue() {
MtpObjectHandle handle = mRequest.getParameter(1);
MtpObjectProperty property = mRequest.getParameter(2);
+ LOGD("GetObjectPropValue %d %s\n", handle,
+ MtpDebug::getObjectPropCodeName(property));
- return mDatabase->getObjectProperty(handle, property, mData);
+ return mDatabase->getObjectPropertyValue(handle, property, mData);
+}
+
+MtpResponseCode MtpServer::doSetObjectPropValue() {
+ MtpObjectHandle handle = mRequest.getParameter(1);
+ MtpObjectProperty property = mRequest.getParameter(2);
+ LOGD("SetObjectPropValue %d %s\n", handle,
+ MtpDebug::getObjectPropCodeName(property));
+
+ return mDatabase->setObjectPropertyValue(handle, property, mData);
+}
+
+MtpResponseCode MtpServer::doGetDevicePropValue() {
+ MtpDeviceProperty property = mRequest.getParameter(1);
+ LOGD("GetDevicePropValue %s\n",
+ MtpDebug::getDevicePropCodeName(property));
+
+ return mDatabase->getDevicePropertyValue(property, mData);
+}
+
+MtpResponseCode MtpServer::doSetDevicePropValue() {
+ MtpDeviceProperty property = mRequest.getParameter(1);
+ LOGD("SetDevicePropValue %s\n",
+ MtpDebug::getDevicePropCodeName(property));
+
+ return mDatabase->setDevicePropertyValue(property, mData);
+}
+
+MtpResponseCode MtpServer::doResetDevicePropValue() {
+ MtpDeviceProperty property = mRequest.getParameter(1);
+ LOGD("ResetDevicePropValue %s\n",
+ MtpDebug::getDevicePropCodeName(property));
+
+ return mDatabase->resetDeviceProperty(property);
}
MtpResponseCode MtpServer::doGetObjectInfo() {
@@ -592,7 +615,7 @@
}
mResponse.setParameter(1, storageID);
- mResponse.setParameter(2, (parent == 0 ? 0xFFFFFFFF: parent));
+ mResponse.setParameter(2, parent);
mResponse.setParameter(3, handle);
return MTP_RESPONSE_OK;
@@ -677,11 +700,24 @@
MtpResponseCode MtpServer::doGetObjectPropDesc() {
MtpObjectProperty propCode = mRequest.getParameter(1);
MtpObjectFormat format = mRequest.getParameter(2);
- MtpProperty* property = getObjectProperty(propCode);
+ LOGD("GetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode),
+ MtpDebug::getFormatCodeName(format));
+ MtpProperty* property = mDatabase->getObjectPropertyDesc(propCode, format);
if (!property)
return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
-
property->write(mData);
+ delete property;
+ return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MtpServer::doGetDevicePropDesc() {
+ MtpDeviceProperty propCode = mRequest.getParameter(1);
+ LOGD("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode));
+ MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode);
+ if (!property)
+ return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+ property->write(mData);
+ delete property;
return MTP_RESPONSE_OK;
}
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 19ccf24..68a6564 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -28,7 +28,6 @@
namespace android {
class MtpDatabase;
-class MtpProperty;
class MtpStorage;
class MtpServer {
@@ -57,9 +56,6 @@
MtpStorageList mStorages;
- MtpPropertyList mObjectProperties;
- MtpPropertyList mDeviceProperties;
-
// handle for new object, set by SendObjectInfo and used by SendObject
MtpObjectHandle mSendObjectHandle;
MtpObjectFormat mSendObjectFormat;
@@ -76,15 +72,10 @@
MtpStorage* getStorage(MtpStorageID id);
void run();
- MtpProperty* getObjectProperty(MtpPropertyCode propCode);
- MtpProperty* getDeviceProperty(MtpPropertyCode propCode);
-
void sendObjectAdded(MtpObjectHandle handle);
void sendObjectRemoved(MtpObjectHandle handle);
private:
- void initObjectProperties();
-
bool handleRequest();
MtpResponseCode doGetDeviceInfo();
@@ -98,12 +89,17 @@
MtpResponseCode doGetObjectReferences();
MtpResponseCode doSetObjectReferences();
MtpResponseCode doGetObjectPropValue();
+ MtpResponseCode doSetObjectPropValue();
+ MtpResponseCode doGetDevicePropValue();
+ MtpResponseCode doSetDevicePropValue();
+ MtpResponseCode doResetDevicePropValue();
MtpResponseCode doGetObjectInfo();
MtpResponseCode doGetObject();
MtpResponseCode doSendObjectInfo();
MtpResponseCode doSendObject();
MtpResponseCode doDeleteObject();
MtpResponseCode doGetObjectPropDesc();
+ MtpResponseCode doGetDevicePropDesc();
};
}; // namespace android
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 56159b5..aa72616 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -610,8 +610,8 @@
* All currently bound service connections. Keys are the IBinder of
* the client's IServiceConnection.
*/
- final HashMap<IBinder, ConnectionRecord> mServiceConnections
- = new HashMap<IBinder, ConnectionRecord>();
+ final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
+ = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
/**
* List of services that we have been asked to start,
@@ -7404,12 +7404,14 @@
if (mServiceConnections.size() > 0) {
if (needSep) pw.println(" ");
pw.println(" Connection bindings to services:");
- Iterator<ConnectionRecord> it
+ Iterator<ArrayList<ConnectionRecord>> it
= mServiceConnections.values().iterator();
while (it.hasNext()) {
- ConnectionRecord r = it.next();
- pw.print(" * "); pw.println(r);
- r.dump(pw, " ");
+ ArrayList<ConnectionRecord> r = it.next();
+ for (int i=0; i<r.size(); i++) {
+ pw.print(" * "); pw.println(r.get(i));
+ r.get(i).dump(pw, " ");
+ }
}
needSep = true;
}
@@ -7687,18 +7689,21 @@
while (it.hasNext()) {
ServiceRecord r = it.next();
if (r.connections.size() > 0) {
- Iterator<ConnectionRecord> jt
+ Iterator<ArrayList<ConnectionRecord>> jt
= r.connections.values().iterator();
while (jt.hasNext()) {
- ConnectionRecord c = jt.next();
- if (c.binding.client != app) {
- try {
- //c.conn.connected(r.className, null);
- } catch (Exception e) {
- // todo: this should be asynchronous!
- Slog.w(TAG, "Exception thrown disconnected servce "
- + r.shortName
- + " from app " + app.processName, e);
+ ArrayList<ConnectionRecord> cl = jt.next();
+ for (int i=0; i<cl.size(); i++) {
+ ConnectionRecord c = cl.get(i);
+ if (c.binding.client != app) {
+ try {
+ //c.conn.connected(r.className, null);
+ } catch (Exception e) {
+ // todo: this should be asynchronous!
+ Slog.w(TAG, "Exception thrown disconnected servce "
+ + r.shortName
+ + " from app " + app.processName, e);
+ }
}
}
}
@@ -7728,7 +7733,9 @@
}
sr.app = null;
sr.executeNesting = 0;
- mStoppingServices.remove(sr);
+ if (mStoppingServices.remove(sr)) {
+ if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
+ }
boolean hasClients = sr.bindings.size() > 0;
if (hasClients) {
@@ -7781,6 +7788,7 @@
ServiceRecord sr = mStoppingServices.get(i);
if (sr.app == app) {
mStoppingServices.remove(i);
+ if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
}
}
@@ -8044,11 +8052,15 @@
if (r.app != null && r.app.persistent) {
info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
}
- for (ConnectionRecord conn : r.connections.values()) {
- if (conn.clientLabel != 0) {
- info.clientPackage = conn.binding.client.info.packageName;
- info.clientLabel = conn.clientLabel;
- break;
+
+ for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
+ for (int i=0; i<connl.size(); i++) {
+ ConnectionRecord conn = connl.get(i);
+ if (conn.clientLabel != 0) {
+ info.clientPackage = conn.binding.client.info.packageName;
+ info.clientLabel = conn.clientLabel;
+ return info;
+ }
}
}
return info;
@@ -8083,9 +8095,11 @@
synchronized (this) {
ServiceRecord r = mServices.get(name);
if (r != null) {
- for (ConnectionRecord conn : r.connections.values()) {
- if (conn.clientIntent != null) {
- return conn.clientIntent;
+ for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
+ for (int i=0; i<conn.size(); i++) {
+ if (conn.get(i).clientIntent != null) {
+ return conn.get(i).clientIntent;
+ }
}
}
}
@@ -8262,8 +8276,8 @@
while (r.pendingStarts.size() > 0) {
try {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
- if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to service: "
- + r.name + " " + r.intent + " args=" + si.intent);
+ if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
+ + r + " " + r.intent + " args=" + si.intent);
if (si.intent == null) {
// If somehow we got a dummy start at the front, then
// just drop it here.
@@ -8276,6 +8290,7 @@
grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
r.packageName, si.intent, si);
}
+ if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING start of " + r);
bumpServiceExecutingLocked(r);
if (!oomAdjusted) {
oomAdjusted = true;
@@ -8292,6 +8307,7 @@
} catch (RemoteException e) {
// Remote process gone... we'll let the normal cleanup take
// care of this.
+ if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
break;
} catch (Exception e) {
Slog.w(TAG, "Unexpected exception", e);
@@ -8308,9 +8324,9 @@
}
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
+ if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING bind of " + r
+ + " in " + i + ": shouldUnbind=" + i.hasBound);
bumpServiceExecutingLocked(r);
- if (DEBUG_SERVICE) Slog.v(TAG, "Connecting binding " + i
- + ": shouldUnbind=" + i.hasBound);
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
if (!rebind) {
i.requested = true;
@@ -8318,6 +8334,7 @@
i.hasBound = true;
i.doRebind = false;
} catch (RemoteException e) {
+ if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
return false;
}
}
@@ -8344,13 +8361,12 @@
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
app.services.add(r);
+ if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING create of " + r + " " + r.intent);
bumpServiceExecutingLocked(r);
updateLruProcessLocked(app, true, true);
boolean created = false;
try {
- if (DEBUG_SERVICE) Slog.v(TAG, "Scheduling start service: "
- + r.name + " " + r.intent);
mStringBuilder.setLength(0);
r.intent.getIntent().toShortString(mStringBuilder, false, true);
EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
@@ -8510,8 +8526,7 @@
return true;
}
- if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up service " + r.name
- + " " + r.intent);
+ if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
// We are now bringing the service up, so no longer in the
// restarting state.
@@ -8562,27 +8577,30 @@
if (!force) {
// XXX should probably keep a count of the number of auto-create
// connections directly in the service.
- Iterator<ConnectionRecord> it = r.connections.values().iterator();
+ Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
while (it.hasNext()) {
- ConnectionRecord cr = it.next();
- if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
- return;
+ ArrayList<ConnectionRecord> cr = it.next();
+ for (int i=0; i<cr.size(); i++) {
+ if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
+ return;
+ }
}
}
}
// Report to all of the connections that the service is no longer
// available.
- Iterator<ConnectionRecord> it = r.connections.values().iterator();
+ Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
while (it.hasNext()) {
- ConnectionRecord c = it.next();
- try {
- // todo: shouldn't be a synchronous call!
- c.conn.connected(r.name, null);
- } catch (Exception e) {
- Slog.w(TAG, "Failure disconnecting service " + r.name +
- " to connection " + c.conn.asBinder() +
- " (in " + c.binding.client.processName + ")", e);
+ ArrayList<ConnectionRecord> c = it.next();
+ for (int i=0; i<c.size(); i++) {
+ try {
+ c.get(i).conn.connected(r.name, null);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failure disconnecting service " + r.name +
+ " to connection " + c.get(i).conn.asBinder() +
+ " (in " + c.get(i).binding.client.processName + ")", e);
+ }
}
}
}
@@ -8596,6 +8614,8 @@
+ ": hasBound=" + ibr.hasBound);
if (r.app != null && r.app.thread != null && ibr.hasBound) {
try {
+ if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING bring down unbind of " + r
+ + " for " + ibr);
bumpServiceExecutingLocked(r);
updateOomAdjLocked(r.app);
ibr.hasBound = false;
@@ -8610,15 +8630,13 @@
}
}
- if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down service " + r.name
- + " " + r.intent);
+ if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
System.identityHashCode(r), r.shortName,
(r.app != null) ? r.app.pid : -1);
mServices.remove(r.name);
mServicesByIntent.remove(r.intent);
- if (localLOGV) Slog.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
r.totalRestartCount = 0;
unscheduleServiceRestartLocked(r);
@@ -8627,8 +8645,7 @@
for (int i=0; i<N; i++) {
if (mPendingServices.get(i) == r) {
mPendingServices.remove(i);
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Removed pending service: " + r.shortName);
+ if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
i--;
N--;
}
@@ -8650,8 +8667,11 @@
r.app.services.remove(r);
if (r.app.thread != null) {
try {
- if (DEBUG_SERVICE) Slog.v(TAG,
- "Stopping service: " + r.shortName);
+ if (DEBUG_SERVICE) {
+ RuntimeException here = new RuntimeException();
+ here.fillInStackTrace();
+ Slog.v(TAG, ">>> EXECUTING stop of " + r, here);
+ }
bumpServiceExecutingLocked(r);
mStoppingServices.add(r);
updateOomAdjLocked(r.app);
@@ -8664,11 +8684,11 @@
updateServiceForegroundLocked(r.app, false);
} else {
if (DEBUG_SERVICE) Slog.v(
- TAG, "Removed service that has no process: " + r.shortName);
+ TAG, "Removed service that has no process: " + r);
}
} else {
if (DEBUG_SERVICE) Slog.v(
- TAG, "Removed service that is not running: " + r.shortName);
+ TAG, "Removed service that is not running: " + r);
}
}
@@ -8703,8 +8723,7 @@
int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service);
if (unscheduleServiceRestartLocked(r)) {
- if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: "
- + r.shortName);
+ if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
}
r.startRequested = true;
r.callStart = false;
@@ -8998,7 +9017,7 @@
if (unscheduleServiceRestartLocked(s)) {
if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
- + s.shortName);
+ + s);
}
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
@@ -9006,7 +9025,12 @@
connection, flags, clientLabel, clientIntent);
IBinder binder = connection.asBinder();
- s.connections.put(binder, c);
+ ArrayList<ConnectionRecord> clist = s.connections.get(binder);
+ if (clist == null) {
+ clist = new ArrayList<ConnectionRecord>();
+ s.connections.put(binder, clist);
+ }
+ clist.add(c);
b.connections.add(c);
if (activity != null) {
if (activity.connections == null) {
@@ -9015,7 +9039,12 @@
activity.connections.add(c);
}
b.client.connections.add(c);
- mServiceConnections.put(binder, c);
+ clist = mServiceConnections.get(binder);
+ if (clist == null) {
+ clist = new ArrayList<ConnectionRecord>();
+ mServiceConnections.put(binder, clist);
+ }
+ clist.add(c);
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
@@ -9066,7 +9095,13 @@
IBinder binder = c.conn.asBinder();
AppBindRecord b = c.binding;
ServiceRecord s = b.service;
- s.connections.remove(binder);
+ ArrayList<ConnectionRecord> clist = s.connections.get(binder);
+ if (clist != null) {
+ clist.remove(c);
+ if (clist.size() == 0) {
+ s.connections.remove(binder);
+ }
+ }
b.connections.remove(c);
if (c.activity != null && c.activity != skipAct) {
if (c.activity.connections != null) {
@@ -9076,7 +9111,13 @@
if (b.client != skipApp) {
b.client.connections.remove(c);
}
- mServiceConnections.remove(binder);
+ clist = mServiceConnections.get(binder);
+ if (clist != null) {
+ clist.remove(c);
+ if (clist.size() == 0) {
+ mServiceConnections.remove(binder);
+ }
+ }
if (b.connections.size() == 0) {
b.intent.apps.remove(b.client);
@@ -9087,6 +9128,8 @@
if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
&& b.intent.hasBound) {
try {
+ if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING unbind of " + s
+ + " from " + b);
bumpServiceExecutingLocked(s);
updateOomAdjLocked(s.app);
b.intent.hasBound = false;
@@ -9109,8 +9152,8 @@
synchronized (this) {
IBinder binder = connection.asBinder();
if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
- ConnectionRecord r = mServiceConnections.get(binder);
- if (r == null) {
+ ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
+ if (clist == null) {
Slog.w(TAG, "Unbind failed: could not find connection for "
+ connection.asBinder());
return false;
@@ -9118,11 +9161,14 @@
final long origId = Binder.clearCallingIdentity();
- removeConnectionLocked(r, null, null);
+ while (clist.size() > 0) {
+ ConnectionRecord r = clist.get(0);
+ removeConnectionLocked(r, null, null);
- if (r.binding.service.app != null) {
- // This could have made the service less important.
- updateOomAdjLocked(r.binding.service.app);
+ if (r.binding.service.app != null) {
+ // This could have made the service less important.
+ updateOomAdjLocked(r.binding.service.app);
+ }
}
Binder.restoreCallingIdentity(origId);
@@ -9145,7 +9191,7 @@
final long origId = Binder.clearCallingIdentity();
- if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING SERVICE " + r.name
+ if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
+ " " + intent + ": " + service);
if (r != null) {
Intent.FilterComparison filter
@@ -9156,26 +9202,29 @@
b.requested = true;
b.received = true;
if (r.connections.size() > 0) {
- Iterator<ConnectionRecord> it
+ Iterator<ArrayList<ConnectionRecord>> it
= r.connections.values().iterator();
while (it.hasNext()) {
- ConnectionRecord c = it.next();
- if (!filter.equals(c.binding.intent.intent)) {
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Not publishing to: " + c);
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Bound intent: " + c.binding.intent.intent);
- if (DEBUG_SERVICE) Slog.v(
- TAG, "Published intent: " + intent);
- continue;
- }
- if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
- try {
- c.conn.connected(r.name, service);
- } catch (Exception e) {
- Slog.w(TAG, "Failure sending service " + r.name +
- " to connection " + c.conn.asBinder() +
- " (in " + c.binding.client.processName + ")", e);
+ ArrayList<ConnectionRecord> clist = it.next();
+ for (int i=0; i<clist.size(); i++) {
+ ConnectionRecord c = clist.get(i);
+ if (!filter.equals(c.binding.intent.intent)) {
+ if (DEBUG_SERVICE) Slog.v(
+ TAG, "Not publishing to: " + c);
+ if (DEBUG_SERVICE) Slog.v(
+ TAG, "Bound intent: " + c.binding.intent.intent);
+ if (DEBUG_SERVICE) Slog.v(
+ TAG, "Published intent: " + intent);
+ continue;
+ }
+ if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
+ try {
+ c.conn.connected(r.name, service);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failure sending service " + r.name +
+ " to connection " + c.conn.asBinder() +
+ " (in " + c.binding.client.processName + ")", e);
+ }
}
}
}
@@ -9236,9 +9285,6 @@
ServiceRecord r = (ServiceRecord)token;
boolean inStopping = mStoppingServices.contains(token);
if (r != null) {
- if (DEBUG_SERVICE) Slog.v(TAG, "DONE EXECUTING SERVICE " + r.name
- + ": nesting=" + r.executeNesting
- + ", inStopping=" + inStopping);
if (r != token) {
Slog.w(TAG, "Done executing service " + r.name
+ " with incorrect token: given " + token
@@ -9295,13 +9341,16 @@
serviceDoneExecutingLocked(r, inStopping);
Binder.restoreCallingIdentity(origId);
} else {
- Slog.w(TAG, "Done executing unknown service " + r.name
- + " with token " + token);
+ Slog.w(TAG, "Done executing unknown service from pid "
+ + Binder.getCallingPid());
}
}
}
public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
+ if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
+ + ": nesting=" + r.executeNesting
+ + ", inStopping=" + inStopping + ", app=" + r.app);
r.executeNesting--;
if (r.executeNesting <= 0 && r.app != null) {
r.app.executingServices.remove(r);
@@ -9309,6 +9358,7 @@
mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
}
if (inStopping) {
+ if (DEBUG_SERVICE) Slog.v(TAG, "doneExecuting remove stopping " + r);
mStoppingServices.remove(r);
}
updateOomAdjLocked(r.app);
@@ -11099,61 +11149,64 @@
}
if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
- Iterator<ConnectionRecord> kt
+ Iterator<ArrayList<ConnectionRecord>> kt
= s.connections.values().iterator();
while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
- // XXX should compute this based on the max of
- // all connected clients.
- ConnectionRecord cr = kt.next();
- if (cr.binding.client == app) {
- // Binding to ourself is not interesting.
- continue;
- }
- if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
- ProcessRecord client = cr.binding.client;
- int myHiddenAdj = hiddenAdj;
- if (myHiddenAdj > client.hiddenAdj) {
- if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
- myHiddenAdj = client.hiddenAdj;
- } else {
- myHiddenAdj = VISIBLE_APP_ADJ;
+ ArrayList<ConnectionRecord> clist = kt.next();
+ for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
+ // XXX should compute this based on the max of
+ // all connected clients.
+ ConnectionRecord cr = clist.get(i);
+ if (cr.binding.client == app) {
+ // Binding to ourself is not interesting.
+ continue;
+ }
+ if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
+ ProcessRecord client = cr.binding.client;
+ int myHiddenAdj = hiddenAdj;
+ if (myHiddenAdj > client.hiddenAdj) {
+ if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
+ myHiddenAdj = client.hiddenAdj;
+ } else {
+ myHiddenAdj = VISIBLE_APP_ADJ;
+ }
+ }
+ int clientAdj = computeOomAdjLocked(
+ client, myHiddenAdj, TOP_APP, true);
+ if (adj > clientAdj) {
+ adj = clientAdj >= VISIBLE_APP_ADJ
+ ? clientAdj : VISIBLE_APP_ADJ;
+ if (!client.hidden) {
+ app.hidden = false;
+ }
+ app.adjType = "service";
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+ .REASON_SERVICE_IN_USE;
+ app.adjSource = cr.binding.client;
+ app.adjTarget = s.name;
+ }
+ if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+ if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ }
}
}
- int clientAdj = computeOomAdjLocked(
- client, myHiddenAdj, TOP_APP, true);
- if (adj > clientAdj) {
- adj = clientAdj >= VISIBLE_APP_ADJ
- ? clientAdj : VISIBLE_APP_ADJ;
- if (!client.hidden) {
- app.hidden = false;
- }
+ ActivityRecord a = cr.activity;
+ //if (a != null) {
+ // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
+ //}
+ if (a != null && adj > FOREGROUND_APP_ADJ &&
+ (a.state == ActivityState.RESUMED
+ || a.state == ActivityState.PAUSING)) {
+ adj = FOREGROUND_APP_ADJ;
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ app.hidden = false;
app.adjType = "service";
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE;
- app.adjSource = cr.binding.client;
+ app.adjSource = a;
app.adjTarget = s.name;
}
- if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
- if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- }
- }
- }
- ActivityRecord a = cr.activity;
- //if (a != null) {
- // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
- //}
- if (a != null && adj > FOREGROUND_APP_ADJ &&
- (a.state == ActivityState.RESUMED
- || a.state == ActivityState.PAUSING)) {
- adj = FOREGROUND_APP_ADJ;
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.hidden = false;
- app.adjType = "service";
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo
- .REASON_SERVICE_IN_USE;
- app.adjSource = a;
- app.adjTarget = s.name;
}
}
}
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 255fbe3..d5b050b 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -72,8 +72,8 @@
final HashMap<Intent.FilterComparison, IntentBindRecord> bindings
= new HashMap<Intent.FilterComparison, IntentBindRecord>();
// All active bindings to the service.
- final HashMap<IBinder, ConnectionRecord> connections
- = new HashMap<IBinder, ConnectionRecord>();
+ final HashMap<IBinder, ArrayList<ConnectionRecord>> connections
+ = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
// IBinder -> ConnectionRecord of all bound clients
ProcessRecord app; // where this service is running or null.
@@ -296,10 +296,12 @@
}
if (connections.size() > 0) {
pw.print(prefix); pw.println("All Connections:");
- Iterator<ConnectionRecord> it = connections.values().iterator();
+ Iterator<ArrayList<ConnectionRecord>> it = connections.values().iterator();
while (it.hasNext()) {
- ConnectionRecord c = it.next();
- pw.print(prefix); pw.print(" "); pw.println(c);
+ ArrayList<ConnectionRecord> c = it.next();
+ for (int i=0; i<c.size(); i++) {
+ pw.print(prefix); pw.print(" "); pw.println(c.get(i));
+ }
}
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 7f7ef60..194c295 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -163,9 +163,13 @@
const uint32_t hwFlags = hw.getFlags();
mFormat = format;
- mReqFormat = format;
mWidth = w;
mHeight = h;
+
+ mReqFormat = format;
+ mReqWidth = w;
+ mReqHeight = h;
+
mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
@@ -361,16 +365,22 @@
uint32_t w, h, f;
{ // scope for the lock
Mutex::Autolock _l(mLock);
- const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight);
- const bool formatChanged = mReqFormat != reqFormat;
- mReqWidth = reqWidth;
- mReqHeight = reqHeight;
- mReqFormat = reqFormat;
- mFixedSize = reqWidth && reqHeight;
- w = reqWidth ? reqWidth : mWidth;
- h = reqHeight ? reqHeight : mHeight;
- f = reqFormat ? reqFormat : mFormat;
- if (fixedSizeChanged || formatChanged) {
+
+ // zero means default
+ if (!reqFormat) reqFormat = mFormat;
+ if (!reqWidth) reqWidth = mWidth;
+ if (!reqHeight) reqHeight = mHeight;
+
+ w = reqWidth;
+ h = reqHeight;
+ f = reqFormat;
+
+ if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
+ (reqFormat != mReqFormat)) {
+ mReqWidth = reqWidth;
+ mReqHeight = reqHeight;
+ mReqFormat = reqFormat;
+
lcblk->reallocateAllExcept(index);
}
}