Merge change Iefd4a388 into eclair
* changes:
Suppress flaky test AppCacheTest#testFreeApplicationCacheSomeFiles
diff --git a/api/current.xml b/api/current.xml
index b4161ae..3abd38b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -6389,6 +6389,72 @@
visibility="public"
>
</field>
+<field name="quickContactBadgeStyleSmallWindowLarge"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843443"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleSmallWindowMedium"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843442"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleSmallWindowSmall"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843441"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleWindowLarge"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843440"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleWindowMedium"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843439"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="quickContactBadgeStyleWindowSmall"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843438"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="radioButtonStyle"
type="int"
transient="false"
@@ -158042,6 +158108,17 @@
visibility="public"
>
</method>
+<method name="isOpaque"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="isPaddingOffsetRequired"
return="boolean"
abstract="false"
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 697ac76..8faef59ba 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -96,6 +96,10 @@
// The extra key used in an intent to the speech recognizer for in-app voice search.
private static final String EXTRA_CALLING_PACKAGE = "calling_package";
+
+ // The string used for privateImeOptions to identify to the IME that it should not show
+ // a microphone button since one already exists in the search dialog.
+ private static final String IME_OPTION_NO_MICROPHONE = "nm";
private static final int SEARCH_PLATE_LEFT_PADDING_GLOBAL = 12;
private static final int SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL = 7;
@@ -543,6 +547,14 @@
mSearchAutoComplete.setInputType(inputType);
mSearchAutoCompleteImeOptions = mSearchable.getImeOptions();
mSearchAutoComplete.setImeOptions(mSearchAutoCompleteImeOptions);
+
+ // If the search dialog is going to show a voice search button, then don't let
+ // the soft keyboard display a microphone button if it would have otherwise.
+ if (mSearchable.getVoiceSearchEnabled()) {
+ mSearchAutoComplete.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE);
+ } else {
+ mSearchAutoComplete.setPrivateImeOptions(null);
+ }
}
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 3265ac4..7f5a1e7 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -330,8 +330,8 @@
* you'll need to update your searchable activity (or other activities) to receive the intents
* as you've defined them.</li>
* <li>Implement a Content Provider that provides suggestions. If you already have one, and it
- * has access to your suggestions data. If not, you'll have to create one.
- * You'll also provide information about your Content Provider in your
+ * has access to your suggestions data, you can use that provider. If not, you'll have to create
+ * one. You'll also provide information about your Content Provider in your
* package's <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">manifest</a>.</li>
* <li>Update your searchable activity's XML configuration file. There are two categories of
* information used for suggestions:
@@ -1181,7 +1181,7 @@
* Bundle appData = new Bundle();
* appData.put...();
* appData.put...();
- * startSearch(null, false, appData);
+ * startSearch(null, false, appData, false);
* return true;
* }</pre>
*
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 00ab7de..1c0ed36 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -54,7 +54,7 @@
// Use the current SDK version code. If we are a development build,
// also allow the previous SDK version + 1.
private static final int sSdkVersion = Build.VERSION.SDK_INT
- + ("REL".equals(Build.VERSION.CODENAME) ? 1 : 0);
+ + ("REL".equals(Build.VERSION.CODENAME) ? 0 : 1);
private static final Object mSync = new Object();
private static Resources mSystem = null;
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 0ce2f7b..f5fed4f 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -46,13 +46,21 @@
/** A constant describing a gyroscope sensor type */
public static final int TYPE_GYROSCOPE = 4;
- /** A constant describing a light sensor type */
+ /**
+ * A constant describing an light sensor type.
+ * See {@link android.hardware.SensorEvent SensorEvent}
+ * for more details.
+ */
public static final int TYPE_LIGHT = 5;
/** A constant describing a pressure sensor type */
public static final int TYPE_PRESSURE = 6;
/** A constant describing a temperature sensor type */
public static final int TYPE_TEMPERATURE = 7;
- /** A constant describing a proximity sensor type */
+ /**
+ * A constant describing an proximity sensor type.
+ * See {@link android.hardware.SensorEvent SensorEvent}
+ * for more details.
+ */
public static final int TYPE_PROXIMITY = 8;
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index cf939c5..32d5691 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -115,8 +115,19 @@
* <p>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD Sensor.TYPE_MAGNETIC_FIELD}:<p>
* All values are in micro-Tesla (uT) and measure the ambient magnetic
* field in the X, Y and Z axis.
- *
- */
+ *
+ * <p>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:<p>
+ *
+ * <p>values[0]: Ambient light level in SI lux units
+ *
+ * <p>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:<p>
+ *
+ * <p>values[0]: Proximity sensor distance measured in centimeters
+ *
+ * <p> Note that some proximity sensors only support a binary "close" or "far" measurement.
+ * In this case, the sensor should report its maxRange value in the "far" state and a value
+ * less than maxRange in the "near" state.
+ */
public final float[] values;
/**
diff --git a/core/java/android/os/PerformanceCollector.java b/core/java/android/os/PerformanceCollector.java
index 4ca1f32..be1cf6d 100644
--- a/core/java/android/os/PerformanceCollector.java
+++ b/core/java/android/os/PerformanceCollector.java
@@ -107,6 +107,36 @@
* @see PerformanceCollector#stopTiming(String)
*/
public void writeStopTiming(Bundle results);
+
+ /**
+ * Callback invoked as last action in
+ * {@link PerformanceCollector#addMeasurement(String, long)} for
+ * reporting an integer type measurement.
+ *
+ * @param label short description of the metric that was measured
+ * @param value long value of the measurement
+ */
+ public void writeMeasurement(String label, long value);
+
+ /**
+ * Callback invoked as last action in
+ * {@link PerformanceCollector#addMeasurement(String, float)} for
+ * reporting a float type measurement.
+ *
+ * @param label short description of the metric that was measured
+ * @param value float value of the measurement
+ */
+ public void writeMeasurement(String label, float value);
+
+ /**
+ * Callback invoked as last action in
+ * {@link PerformanceCollector#addMeasurement(String, String)} for
+ * reporting a string field.
+ *
+ * @param label short description of the metric that was measured
+ * @param value string summary of the measurement
+ */
+ public void writeMeasurement(String label, String value);
}
/**
@@ -385,6 +415,39 @@
return mPerfMeasurement;
}
+ /**
+ * Add an integer type measurement to the collector.
+ *
+ * @param label short description of the metric that was measured
+ * @param value long value of the measurement
+ */
+ public void addMeasurement(String label, long value) {
+ if (mPerfWriter != null)
+ mPerfWriter.writeMeasurement(label, value);
+ }
+
+ /**
+ * Add a float type measurement to the collector.
+ *
+ * @param label short description of the metric that was measured
+ * @param value float value of the measurement
+ */
+ public void addMeasurement(String label, float value) {
+ if (mPerfWriter != null)
+ mPerfWriter.writeMeasurement(label, value);
+ }
+
+ /**
+ * Add a string field to the collector.
+ *
+ * @param label short description of the metric that was measured
+ * @param value string summary of the measurement
+ */
+ public void addMeasurement(String label, String value) {
+ if (mPerfWriter != null)
+ mPerfWriter.writeMeasurement(label, value);
+ }
+
/*
* Starts tracking memory usage, binder transactions, and real & cpu timing.
*/
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index c4711f8..9638262 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -313,6 +313,8 @@
private boolean mIsCallLogComposer = false;
+ private boolean mNeedPhotoForVCard = true;
+
private static final String[] sContactsProjection = new String[] {
Contacts._ID,
};
@@ -332,17 +334,17 @@
private static final String FLAG_TIMEZONE_UTC = "Z";
public VCardComposer(Context context) {
- this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false);
+ this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false, true);
}
public VCardComposer(Context context, String vcardTypeStr,
boolean careHandlerErrors) {
this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr),
- careHandlerErrors, false);
+ careHandlerErrors, false, true);
}
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
- this(context, vcardType, careHandlerErrors, false);
+ this(context, vcardType, careHandlerErrors, false, true);
}
/**
@@ -351,11 +353,12 @@
* @param isCallLogComposer true if this composer is for creating Call Log vCard.
*/
public VCardComposer(Context context, int vcardType, boolean careHandlerErrors,
- boolean isCallLogComposer) {
+ boolean isCallLogComposer, boolean needPhotoInVCard) {
mContext = context;
mVCardType = vcardType;
mCareHandlerErrors = careHandlerErrors;
mIsCallLogComposer = isCallLogComposer;
+ mNeedPhotoForVCard = needPhotoInVCard;
mContentResolver = context.getContentResolver();
mIsV30 = VCardConfig.isV30(vcardType);
@@ -679,7 +682,9 @@
appendWebsites(builder, contentValuesListMap);
appendBirthday(builder, contentValuesListMap);
appendOrganizations(builder, contentValuesListMap);
- appendPhotos(builder, contentValuesListMap);
+ if (mNeedPhotoForVCard) {
+ appendPhotos(builder, contentValuesListMap);
+ }
appendNotes(builder, contentValuesListMap);
// TODO: GroupMembership
diff --git a/core/java/android/util/AttributeSet.java b/core/java/android/util/AttributeSet.java
index 01a7ad4..82592b9 100644
--- a/core/java/android/util/AttributeSet.java
+++ b/core/java/android/util/AttributeSet.java
@@ -34,13 +34,13 @@
* <p>This interface provides an efficient mechanism for retrieving
* data from compiled XML files, which can be retrieved for a particular
* XmlPullParser through {@link Xml#asAttributeSet
- * Xml.getAttributeSet()}. Normally this will return an implementation
+ * Xml.asAttributeSet()}. Normally this will return an implementation
* of the interface that works on top of a generic XmlPullParser, however it
* is more useful in conjunction with compiled XML resources:
*
* <pre>
* XmlPullParser parser = resources.getXml(myResouce);
- * AttributeSet attributes = Xml.getAttributeSet(parser);</pre>
+ * AttributeSet attributes = Xml.asAttributeSet(parser);</pre>
*
* <p>The implementation returned here, unlike using
* the implementation on top of a generic XmlPullParser,
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 74f01cc..2628eb4 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -69,7 +69,7 @@
* Density Independent Pixel unit, where one DIP is one pixel on an
* approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
* providing the baseline of the system's display. Thus on a 160dpi screen
- * this density value will be 1; on a 106 dpi screen it would be .75; etc.
+ * this density value will be 1; on a 120 dpi screen it would be .75; etc.
*
* <p>This value does not exactly follow the real screen size (as given by
* {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index eb3e523..ef306fe 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4956,8 +4956,6 @@
* invalidate/draw passes.
*
* @return True if this View is guaranteed to be fully opaque, false otherwise.
- *
- * @hide Pending API council approval
*/
@ViewDebug.ExportedProperty
public boolean isOpaque() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bf3d26e..596fd98 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3964,8 +3964,7 @@
mHighlightPath = new Path();
if (selStart == selEnd) {
- if ((SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK)
- < BLINK) {
+ if ((SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
if (mHighlightPathBogus) {
mHighlightPath.reset();
mLayout.getCursorPath(selStart, mHighlightPath, mText);
@@ -5344,21 +5343,24 @@
* will happen at measure).
*/
makeNewLayout(want, hintWant, UNKNOWN_BORING, UNKNOWN_BORING,
- mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(), false);
+ mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(),
+ false);
- // In a fixed-height view, so use our new text layout.
- if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
- mLayoutParams.height != LayoutParams.FILL_PARENT) {
- invalidate();
- return;
- }
-
- // Dynamic height, but height has stayed the same,
- // so use our new text layout.
- if (mLayout.getHeight() == oldht &&
- (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
- invalidate();
- return;
+ if (mEllipsize != TextUtils.TruncateAt.MARQUEE) {
+ // In a fixed-height view, so use our new text layout.
+ if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
+ mLayoutParams.height != LayoutParams.FILL_PARENT) {
+ invalidate();
+ return;
+ }
+
+ // Dynamic height, but height has stayed the same,
+ // so use our new text layout.
+ if (mLayout.getHeight() == oldht &&
+ (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
+ invalidate();
+ return;
+ }
}
// We lose: the height has changed and we have a dynamic height.
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index 0f8dff1..455449e 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -1,6 +1,7 @@
#include "GraphicsJNI.h"
#include "SkMaskFilter.h"
#include "SkBlurMaskFilter.h"
+#include "SkTableMaskFilter.h"
#include <jni.h>
@@ -39,6 +40,19 @@
ThrowIAE_IfNull(env, filter);
return filter;
}
+
+ static SkMaskFilter* createTable(JNIEnv* env, jobject, jbyteArray jtable) {
+ AutoJavaByteArray autoTable(env, jtable, 256);
+ return new SkTableMaskFilter((const uint8_t*)autoTable.ptr());
+ }
+
+ static SkMaskFilter* createClipTable(JNIEnv* env, jobject, int min, int max) {
+ return SkTableMaskFilter::CreateClip(min, max);
+ }
+
+ static SkMaskFilter* createGammaTable(JNIEnv* env, jobject, float gamma) {
+ return SkTableMaskFilter::CreateGamma(gamma);
+ }
};
static JNINativeMethod gMaskFilterMethods[] = {
@@ -53,6 +67,12 @@
{ "nativeConstructor", "([FFFF)I", (void*)SkMaskFilterGlue::createEmboss }
};
+static JNINativeMethod gTableMaskFilterMethods[] = {
+ { "nativeNewTable", "([B)I", (void*)SkMaskFilterGlue::createTable },
+ { "nativeNewClip", "(II)I", (void*)SkMaskFilterGlue::createClipTable },
+ { "nativeNewGamma", "(F)I", (void*)SkMaskFilterGlue::createGammaTable }
+};
+
#include <android_runtime/AndroidRuntime.h>
#define REG(env, name, array) \
@@ -67,6 +87,7 @@
REG(env, "android/graphics/MaskFilter", gMaskFilterMethods);
REG(env, "android/graphics/BlurMaskFilter", gBlurMaskFilterMethods);
REG(env, "android/graphics/EmbossMaskFilter", gEmbossMaskFilterMethods);
+ REG(env, "android/graphics/TableMaskFilter", gTableMaskFilterMethods);
return 0;
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bd6e7b4..9058221 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -71,11 +71,6 @@
the slider can be opened (for example, in a pocket or purse). -->
<bool name="config_bypass_keyguard_if_slider_open">true</bool>
- <!-- Flag indicating whether the device supports automatic brightness mode in hardware.
- WARNING - DO NOT USE THIS FEATURE
- Hardware auto brightness support is deprecated and will be removed in the next release. -->
- <bool name="config_hardware_automatic_brightness_available">false</bool>
-
<!-- Flag indicating whether the we should enable the automatic brightness in Settings.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 52e32002..a0b56101 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1194,4 +1194,12 @@
<public type="drawable" name="screen_background_dark_transparent" />
<public type="drawable" name="screen_background_light_transparent" />
<public type="drawable" name="stat_notify_sdcard_prepare" />
+
+ <public type="attr" name="quickContactBadgeStyleWindowSmall" />
+ <public type="attr" name="quickContactBadgeStyleWindowMedium" />
+ <public type="attr" name="quickContactBadgeStyleWindowLarge" />
+ <public type="attr" name="quickContactBadgeStyleSmallWindowSmall" />
+ <public type="attr" name="quickContactBadgeStyleSmallWindowMedium" />
+ <public type="attr" name="quickContactBadgeStyleSmallWindowLarge" />
+
</resources>
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 0830032..cebd2d4 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -18,7 +18,7 @@
</ol>
</li>
<li><a href="#provisional">Using a Provisional API Level</a></li>
- <li><a href="#filtering">Filtering the Reference Documentation by API Level</a></li>
+ <li><a href="#filtering">Filtering the Documentation</a></li>
</ol>
<h2>See also</h2>
diff --git a/docs/html/guide/practices/design/responsiveness.jd b/docs/html/guide/practices/design/responsiveness.jd
index ecd743d..1d5a235 100644
--- a/docs/html/guide/practices/design/responsiveness.jd
+++ b/docs/html/guide/practices/design/responsiveness.jd
@@ -80,7 +80,7 @@
event timeout. These same practices should be followed for any other threads
that display UI, as they are also subject to the same timeouts.</p>
-<p>The specific constraint on IntentReciever execution time emphasizes what
+<p>The specific constraint on IntentReceiver execution time emphasizes what
they were meant to do: small, discrete amounts of work in the background such
as saving a setting or registering a Notification. So as with other methods
called in the main thread, applications should avoid potentially long-running
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 5f0a278..e5a1b5e2 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -847,118 +847,118 @@
<tr>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
<div class="caption">Alarm Clock</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_browser.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_browser.png" alt="Android asset" />
<div class="caption">Browser</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
<div class="caption">Calculator</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
<div class="caption">Calendar</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
<div class="caption">Camcorder</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_camera.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_camera.png" alt="Android asset" />
<div class="caption">Camera</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
<div class="caption">Contacts</div></td>
</tr>
<tr>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
<div class="caption">Dialer</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
<div class="caption">Email</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
<div class="caption">Gallery</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
<div class="caption">Generic application</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_email.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_email.png" alt="Android asset" />
<div class="caption">Gmail</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
<div class="caption">Google Talk</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_IM.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_IM.png" alt="Android asset" />
<div class="caption">IM</div></td>
</tr>
<tr>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_maps.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_maps.png" alt="Android asset" />
<div class="caption">Maps</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
<div class="caption">Market </div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
<div class="caption">Messaging </div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
<div class="caption">Music</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_settings.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_settings.png" alt="Android asset" />
<div class="caption">Settings</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
<div class="caption">Voice Dialer</div></td>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
<div class="caption">Voice Search</div></td>
</tr>
<tr>
<td class="image-caption-i image-list">
- <img src="/images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
+ <img src="{@docRoot}images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
<div class="caption">YouTube</div></td>
</tr>
</table>
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index 8d8b304..0bec658 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -165,4 +165,4 @@
<p>For more information, see the <a
href="{@docRoot}guide/developing/manifest/uses-sdk-element.html"><code><uses-
sdk></code></a> manifest element documentation and the <a
-href="{@docRoot}guide/appendix/api-levels.htmll">API Levels</a> document.</p>
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document.</p>
diff --git a/docs/html/sdk/1.5_r3/upgrading.jd b/docs/html/sdk/1.5_r3/upgrading.jd
index c79b656..f853d25 100644
--- a/docs/html/sdk/1.5_r3/upgrading.jd
+++ b/docs/html/sdk/1.5_r3/upgrading.jd
@@ -187,7 +187,7 @@
<p>If you encounter problems, ensure your ADT is fully uninstalled and then
follow the guide to
-<a href="installingplugin">Installing the ADT Plugin
+<a href="installing.html#installingplugin">Installing the ADT Plugin
for Eclipse</a>.</p>
<h3 id="updateEclipsePrefs">Update your Eclipse SDK Preferences</h3>
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index 66c6bdc..edc77e8 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -360,7 +360,7 @@
</ul>
-<h2 id="troubleshooting">Installation Troubleshooting</h2>
+<h2 id="troubleshooting">Troubleshooting</h2>
<h3>Ubuntu Linux Notes</h3>
diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java
new file mode 100644
index 0000000..a8a7ff0
--- /dev/null
+++ b/graphics/java/android/graphics/TableMaskFilter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 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.graphics;
+
+/**
+ * @hide
+ */
+public class TableMaskFilter extends MaskFilter {
+
+ public TableMaskFilter(byte[] table) {
+ if (table.length < 256) {
+ throw new RuntimeException("table.length must be >= 256");
+ }
+ native_instance = nativeNewTable(table);
+ }
+
+ private TableMaskFilter(int ni) {
+ native_instance = ni;
+ }
+
+ public static TableMaskFilter CreateClipTable(int min, int max) {
+ return new TableMaskFilter(nativeNewClip(min, max));
+ }
+
+ public static TableMaskFilter CreateGammaTable(float gamma) {
+ return new TableMaskFilter(nativeNewGamma(gamma));
+ }
+
+ private static native int nativeNewTable(byte[] table);
+ private static native int nativeNewClip(int min, int max);
+ private static native int nativeNewGamma(float gamma);
+}
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 53466cc..1bc03ac 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -80,6 +80,9 @@
*/
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return
+ if (mRS != null) {
+ mRS.contextSetSurface(null);
+ }
//Log.v(RenderScript.LOG_TAG, "surfaceDestroyed");
}
@@ -88,6 +91,9 @@
* not normally called or subclassed by clients of RSSurfaceView.
*/
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ if (mRS != null) {
+ mRS.contextSetSurface(holder.getSurface());
+ }
//Log.v(RenderScript.LOG_TAG, "surfaceChanged");
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 1f2ea38..f1e5af1 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -64,6 +64,7 @@
native void nDeviceSetConfig(int dev, int param, int value);
native int nContextCreate(int dev, Surface sur, int ver, boolean useDepth);
native void nContextDestroy(int con);
+ native void nContextSetSurface(Surface sur);
native void nContextBindRootScript(int script);
native void nContextBindSampler(int sampler, int slot);
@@ -276,6 +277,11 @@
mMessageThread.start();
}
+ public void contextSetSurface(Surface sur) {
+ mSurface = sur;
+ nContextSetSurface(mSurface);
+ }
+
public void destroy() {
nContextDeinitToClient();
mMessageThread.mRun = false;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index fa3baa20..f3dda41 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -171,6 +171,24 @@
}
static void
+nContextSetSurface(JNIEnv *_env, jobject _this, jobject wnd)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nContextSetSurface, con(%p), surface(%p)", con, (Surface *)wnd);
+
+ Surface * window = NULL;
+ if (wnd == NULL) {
+
+ } else {
+ jclass surface_class = _env->FindClass("android/view/Surface");
+ jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
+ window = (Surface*)_env->GetIntField(wnd, surfaceFieldID);
+ }
+
+ rsContextSetSurface(con, window);
+}
+
+static void
nContextDestroy(JNIEnv *_env, jobject _this, jint con)
{
LOG_API("nContextDestroy, con(%p)", (RsContext)con);
@@ -1328,6 +1346,7 @@
{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy },
{"nDeviceSetConfig", "(III)V", (void*)nDeviceSetConfig },
{"nContextCreate", "(ILandroid/view/Surface;IZ)I", (void*)nContextCreate },
+{"nContextSetSurface", "(Landroid/view/Surface;)V", (void*)nContextSetSurface },
{"nContextDestroy", "(I)V", (void*)nContextDestroy },
{"nContextPause", "()V", (void*)nContextPause },
{"nContextResume", "()V", (void*)nContextResume },
diff --git a/include/binder/MemoryHeapBase.h b/include/binder/MemoryHeapBase.h
index 435540e..d793c24 100644
--- a/include/binder/MemoryHeapBase.h
+++ b/include/binder/MemoryHeapBase.h
@@ -35,7 +35,8 @@
MAP_ONCE = IMemoryHeap::MAP_ONCE,
// memory won't be mapped locally, but will be mapped in the remote
// process.
- DONT_MAP_LOCALLY = 0x00000100
+ DONT_MAP_LOCALLY = 0x00000100,
+ NO_CACHING = 0x00000200
};
/*
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index a7c8a0a..e066177 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -257,11 +257,12 @@
DEVICE_IN_WIRED_HEADSET = 0x100000,
DEVICE_IN_AUX_DIGITAL = 0x200000,
DEVICE_IN_VOICE_CALL = 0x400000,
+ DEVICE_IN_BACK_MIC = 0x800000,
DEVICE_IN_DEFAULT = 0x80000000,
DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
- DEVICE_IN_VOICE_CALL| DEVICE_IN_DEFAULT)
+ DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT)
};
// device connection states used for setDeviceConnectionState()
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 13316a9..8c7392b 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -41,7 +41,9 @@
AUDIO_SOURCE_VOICE_UPLINK = 2,
AUDIO_SOURCE_VOICE_DOWNLINK = 3,
AUDIO_SOURCE_VOICE_CALL = 4,
- AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_CALL,
+ AUDIO_SOURCE_CAMCORDER = 5,
+ AUDIO_SOURCE_VOICE_RECOGNITION = 6,
+ AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_RECOGNITION,
AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type
};
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index 67c2dd8..26cde38 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -32,6 +32,8 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
+struct android_native_buffer_t;
+
namespace android {
const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10;
@@ -602,7 +604,7 @@
copybit_device_t* blitEngine;
int32_t minScale;
int32_t maxScale;
- buffer_handle_t drawSurfaceBuffer;
+ android_native_buffer_t* drawSurfaceBuffer;
};
struct ogles_context_t {
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 2172536..b9c491be 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -93,6 +93,8 @@
void setIndex(int index);
int getIndex() const;
+ void setVerticalStride(uint32_t vstride);
+ uint32_t getVerticalStride() const;
protected:
GraphicBuffer(const Parcel& reply);
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 17ccad6..49145e8 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1272,7 +1272,7 @@
if (version || o.version) {
if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
- return (sdkVersion);
+ return (sdkVersion > o.sdkVersion);
}
if ((minorVersion != o.minorVersion) &&
@@ -1384,7 +1384,7 @@
}
if (version != 0) {
if (settings.sdkVersion != 0 && sdkVersion != 0
- && sdkVersion != settings.sdkVersion) {
+ && sdkVersion > settings.sdkVersion) {
return false;
}
if (settings.minorVersion != 0 && minorVersion != 0
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 0960c81..9c0c850 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1162,7 +1162,7 @@
bool AudioFlinger::MixerThread::threadLoop()
{
- uint32_t sleepTime = 0;
+ uint32_t sleepTime = 1000;
uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
int16_t* curBuf = mMixBuffer;
Vector< sp<Track> > tracksToRemove;
@@ -1224,6 +1224,7 @@
}
standbyTime = systemTime() + kStandbyTimeInNsecs;
+ sleepTime = 1000;
continue;
}
}
@@ -1591,7 +1592,7 @@
bool AudioFlinger::DirectOutputThread::threadLoop()
{
- uint32_t sleepTime = 0;
+ uint32_t sleepTime = 1000;
uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
sp<Track> trackToRemove;
sp<Track> activeTrack;
@@ -1643,6 +1644,7 @@
}
standbyTime = systemTime() + kStandbyTimeInNsecs;
+ sleepTime = 1000;
continue;
}
}
@@ -1879,7 +1881,7 @@
bool AudioFlinger::DuplicatingThread::threadLoop()
{
- uint32_t sleepTime = 0;
+ uint32_t sleepTime = 1000;
uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
int16_t* curBuf = mMixBuffer;
Vector< sp<Track> > tracksToRemove;
@@ -1940,6 +1942,7 @@
}
standbyTime = systemTime() + kStandbyTimeInNsecs;
+ sleepTime = 1000;
continue;
}
}
diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.cpp b/libs/audioflinger/AudioPolicyManagerGeneric.cpp
index 6323859..8cfc204 100644
--- a/libs/audioflinger/AudioPolicyManagerGeneric.cpp
+++ b/libs/audioflinger/AudioPolicyManagerGeneric.cpp
@@ -459,6 +459,61 @@
return NO_ERROR;
}
+status_t AudioPolicyManagerGeneric::dump(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+
+ snprintf(buffer, SIZE, "\nOutputs dump:\n");
+ write(fd, buffer, strlen(buffer));
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
+ write(fd, buffer, strlen(buffer));
+ mOutputs.valueAt(i)->dump(fd);
+ }
+
+ snprintf(buffer, SIZE, "\nInputs dump:\n");
+ write(fd, buffer, strlen(buffer));
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
+ write(fd, buffer, strlen(buffer));
+ mInputs.valueAt(i)->dump(fd);
+ }
+
+ snprintf(buffer, SIZE, "\nStreams dump:\n");
+ write(fd, buffer, strlen(buffer));
+ snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Mute Count Can be muted\n");
+ write(fd, buffer, strlen(buffer));
+ for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+ snprintf(buffer, SIZE, " %02d", i);
+ mStreams[i].dump(buffer + 3, SIZE);
+ write(fd, buffer, strlen(buffer));
+ }
+
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
// AudioPolicyManagerGeneric
// ----------------------------------------------------------------------------
@@ -815,6 +870,35 @@
return refcount;
}
+status_t AudioPolicyManagerGeneric::AudioOutputDescriptor::dump(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Stream refCount\n");
+ result.append(buffer);
+ for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
+ snprintf(buffer, SIZE, " %02d %d\n", i, mRefCount[i]);
+ result.append(buffer);
+ }
+ write(fd, result.string(), result.size());
+
+ return NO_ERROR;
+}
+
// --- AudioInputDescriptor class implementation
AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
@@ -823,4 +907,39 @@
{
}
+status_t AudioPolicyManagerGeneric::AudioInputDescriptor::dump(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Format: %d\n", mFormat);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+
+ return NO_ERROR;
+}
+
+// --- StreamDescriptor class implementation
+
+void AudioPolicyManagerGeneric::StreamDescriptor::dump(char* buffer, size_t size)
+{
+ snprintf(buffer, size, " %02d %02d %02d %02d %d\n",
+ mIndexMin,
+ mIndexMax,
+ mIndexCur,
+ mMuteCount,
+ mCanBeMuted);
+}
+
}; // namespace android
diff --git a/libs/audioflinger/AudioPolicyManagerGeneric.h b/libs/audioflinger/AudioPolicyManagerGeneric.h
index d904520..4997cdf 100644
--- a/libs/audioflinger/AudioPolicyManagerGeneric.h
+++ b/libs/audioflinger/AudioPolicyManagerGeneric.h
@@ -76,6 +76,8 @@
virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
+ virtual status_t dump(int fd);
+
private:
enum routing_strategy {
@@ -93,6 +95,7 @@
public:
AudioOutputDescriptor();
+ status_t dump(int fd);
uint32_t device();
void changeRefCount(AudioSystem::stream_type, int delta);
@@ -115,6 +118,8 @@
public:
AudioInputDescriptor();
+ status_t dump(int fd);
+
uint32_t mSamplingRate; //
uint32_t mFormat; // input configuration
uint32_t mChannels; //
@@ -130,6 +135,8 @@
StreamDescriptor()
: mIndexMin(0), mIndexMax(1), mIndexCur(1), mMuteCount(0), mCanBeMuted(true) {}
+ void dump(char* buffer, size_t size);
+
int mIndexMin; // min volume index
int mIndexMax; // max volume index
int mIndexCur; // current volume index
diff --git a/libs/audioflinger/AudioPolicyService.cpp b/libs/audioflinger/AudioPolicyService.cpp
index f71c99c..9723697 100644
--- a/libs/audioflinger/AudioPolicyService.cpp
+++ b/libs/audioflinger/AudioPolicyService.cpp
@@ -43,6 +43,12 @@
namespace android {
+static const char* kDeadlockedString = "AudioPolicyService may be deadlocked\n";
+static const char* kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
+
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleep = 20000;
+
static bool checkPermission() {
#ifndef HAVE_ANDROID_OS
return true;
@@ -335,17 +341,65 @@
LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
}
+static bool tryLock(Mutex& mutex)
+{
+ bool locked = false;
+ for (int i = 0; i < kDumpLockRetries; ++i) {
+ if (mutex.tryLock() == NO_ERROR) {
+ locked = true;
+ break;
+ }
+ usleep(kDumpLockSleep);
+ }
+ return locked;
+}
+
+status_t AudioPolicyService::dumpInternals(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
+ result.append(buffer);
+
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
{
if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
- dumpPermissionDenial(fd, args);
+ dumpPermissionDenial(fd);
} else {
+ bool locked = tryLock(mLock);
+ if (!locked) {
+ String8 result(kDeadlockedString);
+ write(fd, result.string(), result.size());
+ }
+ dumpInternals(fd);
+ if (mAudioCommandThread != NULL) {
+ mAudioCommandThread->dump(fd);
+ }
+ if (mTonePlaybackThread != NULL) {
+ mTonePlaybackThread->dump(fd);
+ }
+
+ if (mpPolicyManager) {
+ mpPolicyManager->dump(fd);
+ }
+
+ if (locked) mLock.unlock();
}
return NO_ERROR;
}
-status_t AudioPolicyService::dumpPermissionDenial(int fd, const Vector<String16>& args)
+status_t AudioPolicyService::dumpPermissionDenial(int fd)
{
const size_t SIZE = 256;
char buffer[SIZE];
@@ -609,6 +663,36 @@
return false;
}
+status_t AudioPolicyService::AudioCommandThread::dump(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
+ result.append(buffer);
+ write(fd, result.string(), result.size());
+
+ bool locked = tryLock(mLock);
+ if (!locked) {
+ String8 result2(kCmdDeadlockedString);
+ write(fd, result2.string(), result2.size());
+ }
+
+ snprintf(buffer, SIZE, "- Commands:\n");
+ result = String8(buffer);
+ result.append(" Command Time Status Wait pParam\n");
+ for (int i = 0; i < (int)mAudioCommands.size(); i++) {
+ mAudioCommands[i]->dump(buffer, SIZE);
+ result.append(buffer);
+ }
+ write(fd, result.string(), result.size());
+
+ if (locked) mLock.unlock();
+
+ return NO_ERROR;
+}
+
void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
{
AudioCommand *command = new AudioCommand();
@@ -808,4 +892,15 @@
requestExitAndWait();
}
+void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
+{
+ snprintf(buffer, size, " %02d %06d.%03d %03d %01u %p\n",
+ mCommand,
+ (int)ns2s(mTime),
+ (int)ns2ms(mTime)%1000,
+ mStatus,
+ mWaitStatus,
+ mParam);
+}
+
}; // namespace android
diff --git a/libs/audioflinger/AudioPolicyService.h b/libs/audioflinger/AudioPolicyService.h
index 11a1214..7c1bb85 100644
--- a/libs/audioflinger/AudioPolicyService.h
+++ b/libs/audioflinger/AudioPolicyService.h
@@ -111,6 +111,8 @@
AudioPolicyService();
virtual ~AudioPolicyService();
+ status_t dumpInternals(int fd);
+
// Thread used for tone playback and to send audio config commands to audio flinger
// For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone()
// and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause
@@ -133,6 +135,8 @@
AudioCommandThread ();
virtual ~AudioCommandThread();
+ status_t dump(int fd);
+
// Thread virtuals
virtual void onFirstRef();
virtual bool threadLoop();
@@ -149,6 +153,8 @@
// descriptor for requested tone playback event
class AudioCommand {
public:
+ void dump(char* buffer, size_t size);
+
int mCommand; // START_TONE, STOP_TONE ...
nsecs_t mTime; // time stamp
Condition mCond; // condition for status return
@@ -188,7 +194,7 @@
};
// Internal dump utilities.
- status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
+ status_t dumpPermissionDenial(int fd);
Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing device
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index c371a23..86c3df6 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -14,10 +14,13 @@
* limitations under the License.
*/
+#define LOG_TAG "IPCThreadState"
+
#include <binder/IPCThreadState.h>
#include <binder/Binder.h>
#include <binder/BpBinder.h>
+#include <cutils/sched_policy.h>
#include <utils/Debug.h>
#include <utils/Log.h>
#include <utils/TextOutput.h>
@@ -418,7 +421,32 @@
alog << "Processing top-level Command: "
<< getReturnString(cmd) << endl;
}
+
+ bool isTainted = false;
+
+ {
+ SchedPolicy policy;
+ get_sched_policy(getpid(), &policy);
+
+ if (policy == SP_BACKGROUND) {
+ isTainted = true;
+ }
+ }
+
result = executeCommand(cmd);
+
+ // Make sure that after executing the commands that we put the thread back into the
+ // default cgroup.
+ {
+ int pid = getpid();
+ SchedPolicy policy;
+ get_sched_policy(pid, &policy);
+
+ if (!isTainted && policy == SP_BACKGROUND) {
+ LOGW("*** THREAD %p (PID %p) was left in SP_BACKGROUND with a priority of %d\n",
+ (void*)pthread_self(), pid, getpriority(PRIO_PROCESS, pid));
+ }
+ }
}
// Let this thread exit the thread pool if it is no longer
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 5df078f..624f7eb 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -67,7 +67,11 @@
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
mDevice(0), mNeedUnmap(false)
{
- int fd = open(device, O_RDWR);
+ int open_flags = O_RDWR;
+ if (flags & NO_CACHING)
+ open_flags |= O_SYNC;
+
+ int fd = open(device, open_flags);
LOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
if (fd >= 0) {
const size_t pagesize = getpagesize();
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
index 3806a42..c660947 100644
--- a/libs/binder/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -132,7 +132,7 @@
char const * const device = pmemHeap->getDevice();
#if HAVE_ANDROID_OS
if (device) {
- int fd = open(device, O_RDWR);
+ int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
if (fd >= 0) {
int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index a393e2f..865e435 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -36,6 +36,10 @@
ContextResume {
}
+ContextSetSurface {
+ param void *sur
+ }
+
AssignName {
param void *obj
param const char *name
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index b7d1297..38cec64 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -52,6 +52,19 @@
Allocation::~Allocation()
{
+ free(mPtr);
+ mPtr = NULL;
+
+ if (mBufferID) {
+ // Causes a SW crash....
+ //LOGV(" mBufferID %i", mBufferID);
+ //glDeleteBuffers(1, &mBufferID);
+ //mBufferID = 0;
+ }
+ if (mTextureID) {
+ glDeleteTextures(1, &mTextureID);
+ mTextureID = 0;
+ }
}
void Allocation::setCpuWritable(bool)
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index eb388af..3e4cc36 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -85,17 +85,6 @@
}
//eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
- if (mWndSurface) {
- mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
- } else {
- mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig,
- android_createDisplaySurface(),
- NULL);
- }
- checkEglError("eglCreateWindowSurface");
- if (mEGL.mSurface == EGL_NO_SURFACE) {
- LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
- }
mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL);
checkEglError("eglCreateContext");
@@ -104,10 +93,10 @@
}
gGLContextCount++;
- EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
- checkEglError("eglCreateContext", ret);
- if (mEGL.mContext == EGL_NO_CONTEXT) {
- LOGE("eglCreateContext returned EGL_NO_CONTEXT");
+ if (mWndSurface) {
+ setSurface(mWndSurface);
+ } else {
+ setSurface((Surface *)android_createDisplaySurface());
}
eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
@@ -134,12 +123,7 @@
void Context::deinitEGL()
{
- EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- checkEglError("eglCreateContext", ret);
- if (mEGL.mContext == EGL_NO_CONTEXT) {
- LOGE("eglCreateContext returned EGL_NO_CONTEXT");
- }
-
+ setSurface(NULL);
eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
checkEglError("eglDestroyContext");
@@ -311,6 +295,7 @@
while (!rsc->mExit) {
mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
mDraw &= (rsc->mRootScript.get() != NULL);
+ mDraw &= (rsc->mWndSurface != NULL);
if (mDraw) {
mDraw = rsc->runRootScript() && !rsc->mPaused;
@@ -342,6 +327,9 @@
rsc->mStateFragmentStore.deinit(rsc);
ObjectBase::zeroAllUserRef(rsc);
+ rsc->mObjDestroy.mNeedToEmpty = true;
+ rsc->objDestroyOOBRun();
+
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
@@ -350,7 +338,6 @@
rsc->deinitEGL();
pthread_mutex_unlock(&gInitMutex);
- rsc->objDestroyOOBRun();
LOGV("RS Thread exited");
return NULL;
}
@@ -421,6 +408,7 @@
mIO.shutdown();
int status = pthread_join(mThreadId, &res);
+ mObjDestroy.mNeedToEmpty = true;
objDestroyOOBRun();
// Global structure cleanup.
@@ -431,12 +419,39 @@
if (!gThreadTLSKeyCount) {
pthread_key_delete(gThreadTLSKey);
}
+ mDev = NULL;
}
pthread_mutex_unlock(&gInitMutex);
objDestroyOOBDestroy();
}
+void Context::setSurface(Surface *sur)
+{
+ EGLBoolean ret;
+ if (mEGL.mSurface != NULL) {
+ ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ checkEglError("eglMakeCurrent", ret);
+
+ ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+ checkEglError("eglDestroySurface", ret);
+
+ mEGL.mSurface = NULL;
+ }
+
+ mWndSurface = sur;
+ if (mWndSurface != NULL) {
+ mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
+ checkEglError("eglCreateWindowSurface");
+ if (mEGL.mSurface == EGL_NO_SURFACE) {
+ LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
+ }
+
+ ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
+ checkEglError("eglMakeCurrent", ret);
+ }
+}
+
void Context::pause()
{
mPaused = true;
@@ -752,6 +767,11 @@
rsc->resume();
}
+void rsi_ContextSetSurface(Context *rsc, void *sur)
+{
+ rsc->setSurface((Surface *)sur);
+}
+
}
}
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index c80fd5a..bffc55b 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -94,6 +94,7 @@
void pause();
void resume();
+ void setSurface(Surface *sur);
void assignName(ObjectBase *obj, const char *name, uint32_t len);
void removeName(ObjectBase *obj);
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 0008ea4..b7d67cc 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -39,6 +39,7 @@
rsAssert(!mUserRefCount);
rsAssert(!mSysRefCount);
remove();
+ delete[] mName;
}
void ObjectBase::dumpLOGV(const char *op) const
@@ -112,12 +113,7 @@
void ObjectBase::setName(const char *name)
{
- delete mName;
- mName = NULL;
- if (name) {
- mName = new char[strlen(name) +1];
- strcpy(mName, name);
- }
+ setName(name, strlen(name));
}
void ObjectBase::setName(const char *name, uint32_t len)
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 8aa4542..bc40854 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -54,7 +54,7 @@
ObjectBaseRef<ProgramRaster> mRaster;
ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
InvokeFunc_t mInvokables[MAX_SCRIPT_BANKS];
- const char * mScriptText;
+ char * mScriptText;
uint32_t mScriptTextLength;
};
Enviroment_t mEnviroment;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 9da7766..073d98b 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -46,6 +46,8 @@
if (mAccScript) {
accDeleteScript(mAccScript);
}
+ free(mEnviroment.mScriptText);
+ mEnviroment.mScriptText = NULL;
}
void ScriptC::setupScript()
@@ -404,7 +406,11 @@
void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mScript->mEnviroment.mScriptText = text;
+
+ char *t = (char *)malloc(len + 1);
+ memcpy(t, text, len);
+ t[len] = 0;
+ ss->mScript->mEnviroment.mScriptText = t;
ss->mScript->mEnviroment.mScriptTextLength = len;
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index ae124b4..69afc18 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -41,10 +41,6 @@
virtual ~ScriptC();
struct Program_t {
- const char * mScriptText;
- uint32_t mScriptTextLength;
-
-
int mVersionMajor;
int mVersionMinor;
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index 744f2e9..5fd7904 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -40,9 +40,10 @@
LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i)
-: LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
-mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
-mWidthScale(1.0f), mHeightScale(1.0f)
+ : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+ mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
+ mWidthScale(1.0f), mHeightScale(1.0f),
+ mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
{
}
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 6590503..a36304c 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -33,14 +33,13 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
-#include "gralloc_priv.h" // needed for msm / copybit
-
namespace android {
// ---------------------------------------------------------------------------
const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
const char* const LayerBuffer::typeID = "LayerBuffer";
+gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
// ---------------------------------------------------------------------------
@@ -60,6 +59,16 @@
LayerBaseClient::onFirstRef();
mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
const_cast<LayerBuffer *>(this));
+
+ hw_module_t const* module = (hw_module_t const*)sGrallocModule;
+ if (!module) {
+ // NOTE: technically there is a race here, but it shouldn't
+ // cause any problem since hw_get_module() always returns
+ // the same value.
+ if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+ sGrallocModule = (gralloc_module_t const *)module;
+ }
+ }
}
sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
@@ -243,30 +252,36 @@
: mBufferHeap(buffers)
{
NativeBuffer& src(mNativeBuffer);
-
- src.crop.l = 0;
- src.crop.t = 0;
- src.crop.r = buffers.w;
- src.crop.b = buffers.h;
-
- src.img.w = buffers.hor_stride ?: buffers.w;
- src.img.h = buffers.ver_stride ?: buffers.h;
- src.img.format = buffers.format;
- src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
+ src.img.handle = 0;
- // FIXME: gross hack, we should never access private_handle_t from here,
- // but this is needed by msm drivers
- private_handle_t* hnd = new private_handle_t(
- buffers.heap->heapID(), buffers.heap->getSize(), 0);
- hnd->offset = offset;
- src.img.handle = hnd;
+ gralloc_module_t const * module = LayerBuffer::getGrallocModule();
+ if (module && module->perform) {
+ int err = module->perform(module,
+ GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
+ buffers.heap->heapID(), buffers.heap->getSize(),
+ offset, buffers.heap->base(),
+ &src.img.handle);
+
+ if (err == NO_ERROR) {
+ src.crop.l = 0;
+ src.crop.t = 0;
+ src.crop.r = buffers.w;
+ src.crop.b = buffers.h;
+
+ src.img.w = buffers.hor_stride ?: buffers.w;
+ src.img.h = buffers.ver_stride ?: buffers.h;
+ src.img.format = buffers.format;
+ src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
+ }
+ }
}
LayerBuffer::Buffer::~Buffer()
{
NativeBuffer& src(mNativeBuffer);
- if (src.img.handle)
- delete (private_handle_t*)src.img.handle;
+ if (src.img.handle) {
+ native_handle_delete(src.img.handle);
+ }
}
// ============================================================================
@@ -429,6 +444,8 @@
GraphicBuffer::USAGE_HW_TEXTURE,
src.img.w, src.img.handle, false);
+ graphicBuffer->setVerticalStride(src.img.h);
+
err = mLayer.initializeEglImage(graphicBuffer, &mTexture);
}
#endif
@@ -437,9 +454,7 @@
}
if (err != NO_ERROR) {
- // OpenGL fall-back
- GLuint w = 0;
- GLuint h = 0;
+ // slower fallback
GGLSurface t;
t.version = sizeof(GGLSurface);
t.width = src.crop.r;
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 438b711..47482f4 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -91,6 +91,11 @@
copybit_rect_t crop;
};
+ static gralloc_module_t const* sGrallocModule;
+ static gralloc_module_t const* getGrallocModule() {
+ return sGrallocModule;
+ }
+
class Buffer : public LightRefBase<Buffer> {
public:
Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index efe2d78..6a5c8a9 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -226,6 +226,14 @@
return mIndex;
}
+void GraphicBuffer::setVerticalStride(uint32_t vstride) {
+ mVStride = vstride;
+}
+
+uint32_t GraphicBuffer::getVerticalStride() const {
+ return mVStride;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 9bb00c6..0b42cf6 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -135,6 +135,12 @@
/** Voice call uplink + downlink audio source */
public static final int VOICE_CALL = 4;
+
+ /** @hide Microphone audio source with same orientation as camera */
+ public static final int CAMCORDER = 5;
+
+ /** @hide Microphone audio source tuned for voice recognition */
+ public static final int VOICE_RECOGNITION = 6;
}
/**
@@ -274,7 +280,7 @@
* Gets the maximum value for audio sources.
* @see android.media.MediaRecorder.AudioSource
*/
- public static final int getAudioSourceMax() { return AudioSource.VOICE_CALL; }
+ public static final int getAudioSourceMax() { return AudioSource.VOICE_RECOGNITION; }
/**
* Sets the video source to be used for recording. If this method is not
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9d2c779..0b75a2b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1509,6 +1509,7 @@
{
LOGV("pause");
if (mTrack) mTrack->pause();
+ lastWriteTime = 0;
}
void MediaPlayerService::AudioOutput::close()
diff --git a/media/libstagefright/omx/QComHardwareRenderer.cpp b/media/libstagefright/omx/QComHardwareRenderer.cpp
index 7dc368f..c65d1f3 100644
--- a/media/libstagefright/omx/QComHardwareRenderer.cpp
+++ b/media/libstagefright/omx/QComHardwareRenderer.cpp
@@ -126,7 +126,8 @@
master->setDevice("/dev/pmem");
- mMemoryHeap = new MemoryHeapPmem(master, 0);
+ uint32_t heap_flags = master->getFlags() & MemoryHeapBase::NO_CACHING;
+ mMemoryHeap = new MemoryHeapPmem(master, heap_flags);
mMemoryHeap->slap();
ISurface::BufferHeap bufferHeap(
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
index fa0986a..e66e560 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
@@ -226,7 +226,8 @@
* Test case 1: Take a picture and verify all the callback
* functions are called properly.
*/
- @LargeTest
+ // TODO: add this back to LargeTest once bug 2141755 is fixed
+ // @LargeTest
public void testTakePicture() throws Exception {
synchronized (lock) {
initializeMessageLooper();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
index d2809c1..ddf5e0b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
@@ -83,7 +83,8 @@
assertMediaPlaybackActivityHandles("audio/*");
}
- @MediumTest
+ // TODO: temporarily remove from medium suite because it hangs whole suite
+ // @MediumTest
// Checks the MediaPlaybackActivity handles application/itunes. Some servers
// set the Content-type header to application/iTunes (with capital T, but
// the download manager downcasts it) for their MP3 podcasts. This is non
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index 9927edaa..8750098 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -22,6 +22,7 @@
import java.io.FileOutputStream;
import android.test.AndroidTestCase;
import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.MediaProfileReader;
import android.test.suitebuilder.annotation.*;
/**
@@ -38,10 +39,19 @@
public static void testAlbumArt() throws Exception {
Log.v(TAG, "testAlbumArt starts.");
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ MediaProfileReader reader = new MediaProfileReader();
+ boolean supportWMA = reader.getWMAEnable();
+ boolean supportWMV = reader.getWMVEnable();
retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) {
try {
Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]);
+ if ((MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+ (MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+ ) {
+ Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
+ continue;
+ }
retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]);
byte[] albumArt = retriever.extractAlbumArt();
@@ -64,11 +74,20 @@
@LargeTest
public static void testThumbnailCapture() throws Exception {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ MediaProfileReader reader = new MediaProfileReader();
+ boolean supportWMA = reader.getWMAEnable();
+ boolean supportWMV = reader.getWMVEnable();
Log.v(TAG, "Thumbnail processing starts");
long startedAt = System.currentTimeMillis();
for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) {
try {
Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
+ if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+ (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+ ) {
+ Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
+ continue;
+ }
retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
Bitmap bitmap = retriever.captureFrame();
assertTrue(bitmap != null);
@@ -91,10 +110,20 @@
@LargeTest
public static void testMetadataRetrieval() throws Exception {
+ MediaProfileReader reader = new MediaProfileReader();
+ boolean supportWMA = reader.getWMAEnable();
+ boolean supportWMV = reader.getWMVEnable();
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) {
try {
+ Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
+ if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
+ (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
+ ) {
+ Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
+ continue;
+ }
retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
extractAllSupportedMetadataValues(retriever);
} catch(Exception e) {
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 4b9e59b..1bef859 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -46,13 +46,24 @@
static void textureToCopyBitImage(
const GGLSurface* surface, int32_t opFormat,
- buffer_handle_t buffer, copybit_image_t* img)
+ android_native_buffer_t* buffer, copybit_image_t* img)
{
+ uint32_t vstride = 0;
+ if (opFormat == COPYBIT_FORMAT_YCbCr_422_SP ||
+ opFormat == COPYBIT_FORMAT_YCbCr_420_SP) {
+ // NOTE: this static_cast is really not safe b/c we can't know for
+ // sure the buffer passed is of the right type.
+ // However, since we do this only for YUV formats, we should be safe
+ // since only SurfaceFlinger makes use of them.
+ GraphicBuffer* graphicBuffer = static_cast<GraphicBuffer*>(buffer);
+ vstride = graphicBuffer->getVerticalStride();
+ }
+
img->w = surface->stride;
- img->h = surface->height;
+ img->h = vstride ? vstride : surface->height;
img->format = opFormat;
img->base = surface->data;
- img->handle = (native_handle_t *)buffer;
+ img->handle = (native_handle_t *)buffer->handle;
}
struct clipRectRegion : public copybit_region_t {
@@ -74,6 +85,7 @@
static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
return 0;
}
+public:
copybit_rect_t r;
};
@@ -278,8 +290,8 @@
copybit_device_t* copybit = c->copybits.blitEngine;
copybit_image_t src;
- buffer_handle_t source_hnd = textureObject->buffer->handle;
- textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src);
+ textureToCopyBitImage(&textureObject->surface, opFormat,
+ textureObject->buffer, &src);
copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
/*
@@ -359,8 +371,8 @@
}
copybit_image_t dst;
- buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer;
- textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst);
+ textureToCopyBitImage(&cbSurface, cbSurface.format,
+ c->copybits.drawSurfaceBuffer, &dst);
copybit_rect_t drect = {x, y, x+w, y+h};
@@ -421,6 +433,20 @@
(enables & GGL_ENABLE_DITHER) ?
COPYBIT_ENABLE : COPYBIT_DISABLE);
clipRectRegion it(c);
+
+ LOGD_IF(0,
+ "dst={%d, %d, %d, %p, %p}, "
+ "src={%d, %d, %d, %p, %p}, "
+ "drect={%d,%d,%d,%d}, "
+ "srect={%d,%d,%d,%d}, "
+ "it={%d,%d,%d,%d}, " ,
+ dst.w, dst.h, dst.format, dst.base, dst.handle,
+ src.w, src.h, src.format, src.base, src.handle,
+ drect.l, drect.t, drect.r, drect.b,
+ srect.l, srect.t, srect.r, srect.b,
+ it.r.l, it.r.t, it.r.r, it.r.b
+ );
+
err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
}
if (err != NO_ERROR) {
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index d04900e..80ddc02 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -651,7 +651,7 @@
if (supportedCopybitsDestinationFormat(buffer.format)) {
buffer_handle_t handle = this->buffer->handle;
if (handle != NULL) {
- gl->copybits.drawSurfaceBuffer = handle;
+ gl->copybits.drawSurfaceBuffer = this->buffer;
}
}
}
diff --git a/opengl/libagl/matrix.cpp b/opengl/libagl/matrix.cpp
index 21ef50e..3c50977 100644
--- a/opengl/libagl/matrix.cpp
+++ b/opengl/libagl/matrix.cpp
@@ -741,20 +741,19 @@
void point4__mvui(transform_t const* mx, vec4_t* lhs, vec4_t const* rhs) {
// this used for transforming light positions back to object space.
- // Lights have 3 components positions, so w is always 1.
- // however, it is used as a switch for directional lights, so we need
+ // w is used as a switch for directional lights, so we need
// to preserve it.
const GLfixed* const m = mx->matrix.m;
const GLfixed rx = rhs->x;
const GLfixed ry = rhs->y;
const GLfixed rz = rhs->z;
- lhs->x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]);
- lhs->y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
- lhs->z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
- lhs->w = rhs->w;
+ const GLfixed rw = rhs->w;
+ lhs->x = mla4(rx, m[ 0], ry, m[ 4], rz, m[ 8], rw, m[12]);
+ lhs->y = mla4(rx, m[ 1], ry, m[ 5], rz, m[ 9], rw, m[13]);
+ lhs->z = mla4(rx, m[ 2], ry, m[ 6], rz, m[10], rw, m[14]);
+ lhs->w = rw;
}
-
void point2__nop(transform_t const*, vec4_t* lhs, vec4_t const* rhs) {
lhs->z = 0;
lhs->w = 0x10000;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3efb678..c22c21b 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -1641,8 +1641,13 @@
if (dp == 0) {
return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
}
- // since we don't have a way to know which implementation to call,
- // we're calling all of them
+
+ /* Since we don't have a way to know which implementation to call,
+ * we're calling all of them. If at least one of the implementation
+ * succeeded, this is a success.
+ */
+
+ EGLint currentError = eglGetError();
EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS];
bool success = false;
@@ -1659,9 +1664,24 @@
}
}
}
- if (!success)
+
+ if (!success) {
+ // failure, if there was an error when we entered this function,
+ // the error flag must not be updated.
+ // Otherwise, the error is whatever happened in the implementation
+ // that faulted.
+ if (currentError != EGL_SUCCESS) {
+ setError(currentError, EGL_NO_IMAGE_KHR);
+ }
return EGL_NO_IMAGE_KHR;
-
+ } else {
+ // In case of success, we need to clear all error flags
+ // (especially those caused by the implementation that didn't
+ // succeed). TODO: we could avoid this if we knew this was
+ // a "full" success (all implementation succeeded).
+ eglGetError();
+ }
+
egl_image_t* result = new egl_image_t(dpy, ctx);
memcpy(result->images, implImages, sizeof(implImages));
return (EGLImageKHR)result;
diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp
index 992a10c..6842940 100644
--- a/opengl/tests/linetex/linetex.cpp
+++ b/opengl/tests/linetex/linetex.cpp
@@ -68,7 +68,7 @@
glBindTexture(GL_TEXTURE_2D, 0);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -77,7 +77,9 @@
glEnable(GL_TEXTURE_2D);
glColor4f(1,1,1,1);
- const uint16_t t16[64] = { 0xFFFF, 0xF800, 0x07E0, 0x001F };
+
+ // default pack-alignment is 4
+ const uint16_t t16[64] = { 0xFFFF, 0, 0xF800, 0, 0x07E0, 0, 0x001F, 0 };
const GLfloat vertices[4][2] = {
{ w/2, 0 },
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 82a7c1c..754e6e5 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -76,6 +76,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Random;
class BackupManagerService extends IBackupManager.Stub {
private static final String TAG = "BackupManagerService";
@@ -85,6 +86,9 @@
// trigger an immediate pass.
private static final long BACKUP_INTERVAL = AlarmManager.INTERVAL_HOUR;
+ // Random variation in backup scheduling time to avoid server load spikes
+ private static final int FUZZ_MILLIS = 5 * 60 * 1000;
+
// The amount of time between the initial provisioning of the device and
// the first backup pass.
private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
@@ -1949,9 +1953,15 @@
}
private void startBackupAlarmsLocked(long delayBeforeFirstBackup) {
- long when = System.currentTimeMillis() + delayBeforeFirstBackup;
- mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, when,
- BACKUP_INTERVAL, mRunBackupIntent);
+ // We used to use setInexactRepeating(), but that may be linked to
+ // backups running at :00 more often than not, creating load spikes.
+ // Schedule at an exact time for now, and also add a bit of "fuzz".
+
+ Random random = new Random();
+ long when = System.currentTimeMillis() + delayBeforeFirstBackup +
+ random.nextInt(FUZZ_MILLIS);
+ mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when,
+ BACKUP_INTERVAL + random.nextInt(FUZZ_MILLIS), mRunBackupIntent);
mNextBackupPass = when;
}
diff --git a/services/java/com/android/server/HardwareService.java b/services/java/com/android/server/HardwareService.java
index 7c56a30..b1d58ce 100755
--- a/services/java/com/android/server/HardwareService.java
+++ b/services/java/com/android/server/HardwareService.java
@@ -59,8 +59,6 @@
private boolean mAttentionLightOn;
private boolean mPulsing;
- private boolean mAutoBrightnessAvailable;
-
private class Vibration implements IBinder.DeathRecipient {
private final IBinder mToken;
private final long mTimeout;
@@ -131,9 +129,6 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
context.registerReceiver(mIntentReceiver, filter);
-
- mAutoBrightnessAvailable = context.getResources().getBoolean(
- com.android.internal.R.bool.config_hardware_automatic_brightness_available);
}
protected void finalize() throws Throwable {
@@ -287,12 +282,6 @@
setLight_native(mNativePointer, light, color, mode, onMS, offMS);
}
- void setAutoBrightness_UNCHECKED(boolean on) {
- if (mAutoBrightnessAvailable) {
- setAutoBrightness_native(mNativePointer, on);
- }
- }
-
public void setAttentionLight(boolean on) {
// Not worthy of a permission. We shouldn't have a flashlight permission.
synchronized (this) {
@@ -493,7 +482,6 @@
private static native int init_native();
private static native void finalize_native(int ptr);
- private static native void setAutoBrightness_native(int ptr, boolean automatic);
private static native void setLight_native(int ptr, int light, int color, int mode,
int onMS, int offMS);
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 4bf606d..93b469f 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -211,7 +211,7 @@
private long mScreenOnStartTime;
private boolean mPreventScreenOn;
private int mScreenBrightnessOverride = -1;
- private boolean mHasHardwareAutoBrightness;
+ private boolean mUseSoftwareAutoBrightness;
private boolean mAutoBrightessEnabled;
private int[] mAutoBrightnessLevels;
private int[] mLcdBacklightValues;
@@ -438,9 +438,11 @@
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Resources resources = mContext.getResources();
- mHasHardwareAutoBrightness = resources.getBoolean(
- com.android.internal.R.bool.config_hardware_automatic_brightness_available);
- if (!mHasHardwareAutoBrightness) {
+
+ // read settings for auto-brightness
+ mUseSoftwareAutoBrightness = resources.getBoolean(
+ com.android.internal.R.bool.config_automatic_brightness_available);
+ if (mUseSoftwareAutoBrightness) {
mAutoBrightnessLevels = resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels);
mLcdBacklightValues = resources.getIntArray(
@@ -479,7 +481,7 @@
// And explicitly do the initial update of our cached settings
updateGservicesValues();
- if (mAutoBrightessEnabled && !mHasHardwareAutoBrightness) {
+ if (mUseSoftwareAutoBrightness) {
// turn the screen on
setPowerState(SCREEN_BRIGHT);
} else {
@@ -581,7 +583,7 @@
switch (wl.flags & LOCK_MASK)
{
case PowerManager.FULL_WAKE_LOCK:
- if (mAutoBrightessEnabled && !mHasHardwareAutoBrightness) {
+ if (mUseSoftwareAutoBrightness) {
wl.minState = SCREEN_BRIGHT;
} else {
wl.minState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
@@ -887,7 +889,7 @@
pw.println(" mLightSensorEnabled=" + mLightSensorEnabled);
pw.println(" mLightSensorValue=" + mLightSensorValue);
pw.println(" mLightSensorPendingValue=" + mLightSensorPendingValue);
- pw.println(" mHasHardwareAutoBrightness=" + mHasHardwareAutoBrightness);
+ pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
mScreenBrightness.dump(pw, " mScreenBrightness: ");
mKeyboardBrightness.dump(pw, " mKeyboardBrightness: ");
@@ -1290,8 +1292,8 @@
private int setScreenStateLocked(boolean on) {
int err = Power.setScreenState(on);
- if (err == 0 && !mHasHardwareAutoBrightness) {
- enableLightSensor(on && mAutoBrightessEnabled);
+ if (err == 0 && mUseSoftwareAutoBrightness) {
+ enableLightSensor(on);
if (!on) {
// make sure button and key backlights are off too
mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, 0);
@@ -1337,7 +1339,7 @@
return;
}
- if (!mDoneBooting && !(mAutoBrightessEnabled && !mHasHardwareAutoBrightness)) {
+ if (!mDoneBooting && !mUseSoftwareAutoBrightness) {
newState |= ALL_BRIGHT;
}
@@ -1758,7 +1760,8 @@
try {
if (mScreenBrightnessOverride >= 0) {
return mScreenBrightnessOverride;
- } else if (mLightSensorBrightness >= 0 && !mHasHardwareAutoBrightness) {
+ } else if (mLightSensorBrightness >= 0 && mUseSoftwareAutoBrightness
+ && mAutoBrightessEnabled) {
return mLightSensorBrightness;
}
final int brightness = Settings.System.getInt(mContext.getContentResolver(),
@@ -1783,6 +1786,8 @@
}
private void forceUserActivityLocked() {
+ // cancel animation so userActivity will succeed
+ mScreenBrightness.animating = false;
boolean savedActivityAllowed = mUserActivityAllowed;
mUserActivityAllowed = true;
userActivity(SystemClock.uptimeMillis(), false);
@@ -1849,8 +1854,7 @@
if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
// Only turn on button backlights if a button was pressed
// and auto brightness is disabled
- if (eventType == BUTTON_EVENT &&
- !(mAutoBrightessEnabled && !mHasHardwareAutoBrightness)) {
+ if (eventType == BUTTON_EVENT && !mUseSoftwareAutoBrightness) {
mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);
} else {
// don't clear button/keyboard backlights when the screen is touched.
@@ -1908,14 +1912,17 @@
Log.d(TAG, "lightSensorChangedLocked " + value);
}
- if (mHasHardwareAutoBrightness) return;
-
if (mLightSensorValue != value) {
mLightSensorValue = value;
if ((mPowerState & BATTERY_LOW_BIT) == 0) {
int lcdValue = getAutoBrightnessValue(value, mLcdBacklightValues);
int buttonValue = getAutoBrightnessValue(value, mButtonBacklightValues);
- int keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
+ int keyboardValue;
+ if (mKeyboardVisible) {
+ keyboardValue = getAutoBrightnessValue(value, mKeyboardBacklightValues);
+ } else {
+ keyboardValue = 0;
+ }
mLightSensorBrightness = lcdValue;
if (mDebugLightSensor) {
@@ -1925,7 +1932,7 @@
}
boolean startAnimation = false;
- if (mScreenBrightnessOverride < 0) {
+ if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
if (ANIMATE_SCREEN_LIGHTS) {
if (mScreenBrightness.setTargetLocked(lcdValue,
AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_SCREEN_BRIGHTNESS,
@@ -2037,6 +2044,14 @@
// will take care of turning on due to a true change to the lid
// switch and synchronized with the lock screen.
if ((mPowerState & SCREEN_ON_BIT) != 0) {
+ if (mUseSoftwareAutoBrightness) {
+ // force recompute of backlight values
+ if (mLightSensorValue >= 0) {
+ int value = (int)mLightSensorValue;
+ mLightSensorValue = -1;
+ lightSensorChangedLocked(value);
+ }
+ }
userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
}
}
@@ -2049,26 +2064,20 @@
public void enableUserActivity(boolean enabled) {
synchronized (mLocks) {
mUserActivityAllowed = enabled;
- mLastEventTime = SystemClock.uptimeMillis(); // we might need to pass this in
}
}
private void setScreenBrightnessMode(int mode) {
boolean enabled = (mode == SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
- if (mAutoBrightessEnabled != enabled) {
+ if (mUseSoftwareAutoBrightness && mAutoBrightessEnabled != enabled) {
mAutoBrightessEnabled = enabled;
- // reset computed brightness
- mLightSensorValue = -1;
- mLightSensorBrightness = -1;
-
- if (mHasHardwareAutoBrightness) {
- // When setting auto-brightness, must reset the brightness afterwards
- mHardware.setAutoBrightness_UNCHECKED(enabled);
- if (screenIsOn()) {
- setBacklightBrightness((int)mScreenBrightness.curValue);
+ if (screenIsOn()) {
+ // force recompute of backlight values
+ if (mLightSensorValue >= 0) {
+ int value = (int)mLightSensorValue;
+ mLightSensorValue = -1;
+ lightSensorChangedLocked(value);
}
- } else {
- enableLightSensor(screenIsOn() && enabled);
}
}
}
@@ -2222,9 +2231,9 @@
mSensorManager = new SensorManager(mHandlerThread.getLooper());
mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
// don't bother with the light sensor if auto brightness is handled in hardware
- if (!mHasHardwareAutoBrightness) {
+ if (mUseSoftwareAutoBrightness) {
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
- enableLightSensor(mAutoBrightessEnabled);
+ enableLightSensor(true);
}
synchronized (mLocks) {
@@ -2266,7 +2275,8 @@
// Don't let applications turn the screen all the way off
brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BACKLIGHT, brightness);
- mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD, brightness);
+ mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_KEYBOARD,
+ (mKeyboardVisible ? brightness : 0));
mHardware.setLightBrightness_UNCHECKED(HardwareService.LIGHT_ID_BUTTONS, brightness);
long identity = Binder.clearCallingIdentity();
try {
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 59e9832..8d73904 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -692,6 +692,7 @@
mTicker.addEntry(n, StatusBarIcon.getIcon(mContext, data), n.tickerText);
}
}
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
}
// icon
@@ -950,7 +951,9 @@
panelSlightlyVisible(true);
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
- mExpandedDialog.show();
+ mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ mExpandedDialog.getWindow().setAttributes(mExpandedParams);
mExpandedView.requestFocus(View.FOCUS_FORWARD);
mTrackingView.setVisibility(View.VISIBLE);
@@ -1027,7 +1030,9 @@
}
mExpandedVisible = false;
panelSlightlyVisible(false);
- mExpandedDialog.hide();
+ mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ mExpandedDialog.getWindow().setAttributes(mExpandedParams);
mTrackingView.setVisibility(View.GONE);
if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
@@ -1056,6 +1061,7 @@
else if (mAnimY < mStatusBarView.getHeight()) {
if (SPEW) Log.d(TAG, "Animation completed to collapsed state.");
mAnimating = false;
+ updateExpandedViewPos(0);
performCollapse();
}
else {
@@ -1508,17 +1514,18 @@
}
}
+ final int disph = mDisplay.getHeight();
lp = mExpandedDialog.getWindow().getAttributes();
lp.width = ViewGroup.LayoutParams.FILL_PARENT;
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
lp.x = 0;
- lp.y = 0;
+ mTrackingPosition = lp.y = -disph; // sufficiently large negative
lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
- | WindowManager.LayoutParams.FLAG_DITHER;
+ | WindowManager.LayoutParams.FLAG_DITHER
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.format = pixelFormat;
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.setTitle("StatusBarExpanded");
@@ -1531,7 +1538,6 @@
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
mExpandedDialog.show();
- mExpandedDialog.hide();
FrameLayout hack = (FrameLayout)mExpandedView.getParent();
hack.setForeground(null);
}
@@ -1558,15 +1564,24 @@
+ " mTrackingPosition=" + mTrackingPosition);
}
- // If the expanded view is not visible, there is no reason to do
- // any work.
- if (!mExpandedVisible) {
- return;
- }
-
- // tracking view...
int h = mStatusBarView.getHeight();
int disph = mDisplay.getHeight();
+
+ // If the expanded view is not visible, make sure they're still off screen.
+ // Maybe the view was resized.
+ if (!mExpandedVisible) {
+ if (mTrackingView != null) {
+ mTrackingPosition = mTrackingParams.y = -disph;
+ WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
+ }
+ if (mExpandedParams != null) {
+ mExpandedParams.y = -disph;
+ mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+ }
+ return;
+ }
+
+ // tracking view...
int pos;
if (expandedPosition == EXPANDED_FULL_OPEN) {
pos = h;
@@ -1677,7 +1692,7 @@
private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
public void onClick(View v) {
mNotificationCallbacks.onClearAll();
- performCollapse();
+ addPendingOp(OP_EXPAND, null, false);
}
};
diff --git a/services/java/com/android/server/status/TrackingPatternView.java b/services/java/com/android/server/status/TrackingPatternView.java
index 0ae9984..4cb8eff 100644
--- a/services/java/com/android/server/status/TrackingPatternView.java
+++ b/services/java/com/android/server/status/TrackingPatternView.java
@@ -55,8 +55,6 @@
final int textureWidth = mTextureWidth;
final int textureHeight = mTextureHeight;
- Log.d("TrackingPatternView", "width=" + width + " textureWidth=" + textureWidth);
-
int x = 0;
int y;
diff --git a/services/jni/com_android_server_HardwareService.cpp b/services/jni/com_android_server_HardwareService.cpp
index a17e29f..22d4bd8 100644
--- a/services/jni/com_android_server_HardwareService.cpp
+++ b/services/jni/com_android_server_HardwareService.cpp
@@ -100,18 +100,6 @@
free(devices);
}
-static void setAutoBrightness_native(JNIEnv *env, jobject clazz, int ptr,
- jboolean automatic)
-{
- Devices* devices = (Devices*)ptr;
-
- if (devices->lights[LIGHT_INDEX_BACKLIGHT] == NULL) {
- return;
- }
-
- devices->lights[LIGHT_INDEX_BACKLIGHT]->set_als_mode(automatic ? 0 : 1);
-}
-
static void setLight_native(JNIEnv *env, jobject clazz, int ptr,
int light, int colorARGB, int flashMode, int onMS, int offMS)
{
@@ -146,7 +134,6 @@
static JNINativeMethod method_table[] = {
{ "init_native", "()I", (void*)init_native },
{ "finalize_native", "(I)V", (void*)finalize_native },
- { "setAutoBrightness_native", "(IZ)V", (void*)setAutoBrightness_native },
{ "setLight_native", "(IIIIII)V", (void*)setLight_native },
{ "vibratorOn", "(J)V", (void*)vibratorOn },
{ "vibratorOff", "()V", (void*)vibratorOff }
diff --git a/test-runner/android/test/InstrumentationTestRunner.java b/test-runner/android/test/InstrumentationTestRunner.java
index b9978d6..773d7a9 100644
--- a/test-runner/android/test/InstrumentationTestRunner.java
+++ b/test-runner/android/test/InstrumentationTestRunner.java
@@ -227,17 +227,22 @@
*/
private static final String REPORT_KEY_COVERAGE_PATH = "coverageFilePath";
/**
+ * If included at the start of reporting keys, this prefix marks the key as a performance
+ * metric.
+ */
+ private static final String REPORT_KEY_PREFIX = "performance.";
+ /**
* If included in the status or final bundle sent to an IInstrumentationWatcher, this key
* reports the cpu time in milliseconds of the current test.
*/
private static final String REPORT_KEY_PERF_CPU_TIME =
- "performance." + PerformanceCollector.METRIC_KEY_CPU_TIME;
+ REPORT_KEY_PREFIX + PerformanceCollector.METRIC_KEY_CPU_TIME;
/**
* If included in the status or final bundle sent to an IInstrumentationWatcher, this key
* reports the run time in milliseconds of the current test.
*/
private static final String REPORT_KEY_PERF_EXECUTION_TIME =
- "performance." + PerformanceCollector.METRIC_KEY_EXECUTION_TIME;
+ REPORT_KEY_PREFIX + PerformanceCollector.METRIC_KEY_EXECUTION_TIME;
/**
* The test is starting.
@@ -739,11 +744,9 @@
}
public void writeEndSnapshot(Bundle results) {
- // Copy all snapshot data fields as type long into mResults, which
- // is outputted via Instrumentation.finish
- for (String key : results.keySet()) {
- mResults.putLong(key, results.getLong(key));
- }
+ // Copy all snapshot data fields into mResults, which is outputted
+ // via Instrumentation.finish
+ mResults.putAll(results);
}
public void writeStartTiming(String label) {
@@ -768,6 +771,18 @@
}
}
+ public void writeMeasurement(String label, long value) {
+ mTestResult.putLong(REPORT_KEY_PREFIX + label, value);
+ }
+
+ public void writeMeasurement(String label, float value) {
+ mTestResult.putFloat(REPORT_KEY_PREFIX + label, value);
+ }
+
+ public void writeMeasurement(String label, String value) {
+ mTestResult.putString(REPORT_KEY_PREFIX + label, value);
+ }
+
// TODO report the end of the cycle
}
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java
index d0fdff4..25b6e0e 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/os/PerformanceCollectorTest.java
@@ -19,8 +19,9 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.os.PerformanceCollector;
+import android.os.Process;
import android.os.PerformanceCollector.PerformanceResultsWriter;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
mPerfCollector = null;
}
+ @SmallTest
public void testBeginSnapshotNoWriter() throws Exception {
mPerfCollector.beginSnapshot("testBeginSnapshotNoWriter");
@@ -54,15 +56,16 @@
assertEquals(2, snapshot.size());
}
- @LargeTest
+ @SmallTest
public void testEndSnapshotNoWriter() throws Exception {
mPerfCollector.beginSnapshot("testEndSnapshotNoWriter");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
Bundle snapshot = mPerfCollector.endSnapshot();
verifySnapshotBundle(snapshot);
}
+ @SmallTest
public void testStartTimingNoWriter() throws Exception {
mPerfCollector.startTiming("testStartTimingNoWriter");
@@ -73,21 +76,23 @@
verifyTimingBundle(measurement, new ArrayList<String>());
}
+ @SmallTest
public void testAddIterationNoWriter() throws Exception {
mPerfCollector.startTiming("testAddIterationNoWriter");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
Bundle iteration = mPerfCollector.addIteration("timing1");
verifyIterationBundle(iteration, "timing1");
}
+ @SmallTest
public void testStopTimingNoWriter() throws Exception {
mPerfCollector.startTiming("testStopTimingNoWriter");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("timing2");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("timing3");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing = mPerfCollector.stopTiming("timing4");
ArrayList<String> labels = new ArrayList<String>();
@@ -97,6 +102,7 @@
verifyTimingBundle(timing, labels);
}
+ @SmallTest
public void testBeginSnapshot() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
@@ -110,19 +116,20 @@
assertEquals(2, snapshot.size());
}
- @LargeTest
+ @SmallTest
public void testEndSnapshot() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
mPerfCollector.beginSnapshot("testEndSnapshot");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
Bundle snapshot1 = mPerfCollector.endSnapshot();
Bundle snapshot2 = writer.snapshotResults;
- assertTrue(snapshot1.equals(snapshot2));
+ assertEqualsBundle(snapshot1, snapshot2);
verifySnapshotBundle(snapshot1);
}
+ @SmallTest
public void testStartTiming() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
@@ -136,21 +143,23 @@
verifyTimingBundle(measurement, new ArrayList<String>());
}
+ @SmallTest
public void testAddIteration() throws Exception {
mPerfCollector.startTiming("testAddIteration");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
Bundle iteration = mPerfCollector.addIteration("timing5");
verifyIterationBundle(iteration, "timing5");
}
+ @SmallTest
public void testStopTiming() throws Exception {
mPerfCollector.startTiming("testStopTiming");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("timing6");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("timing7");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing = mPerfCollector.stopTiming("timing8");
ArrayList<String> labels = new ArrayList<String>();
@@ -160,28 +169,90 @@
verifyTimingBundle(timing, labels);
}
- // TODO: flaky test
- // @LargeTest
+ @SmallTest
+ public void testAddMeasurementLong() throws Exception {
+ MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
+ mPerfCollector.setPerformanceResultsWriter(writer);
+ mPerfCollector.startTiming("testAddMeasurementLong");
+ mPerfCollector.addMeasurement("testAddMeasurementLongZero", 0);
+ mPerfCollector.addMeasurement("testAddMeasurementLongPos", 348573);
+ mPerfCollector.addMeasurement("testAddMeasurementLongNeg", -19354);
+ mPerfCollector.stopTiming("");
+
+ assertEquals("testAddMeasurementLong", writer.timingLabel);
+ Bundle results = writer.timingResults;
+ assertEquals(4, results.size());
+ assertTrue(results.containsKey("testAddMeasurementLongZero"));
+ assertEquals(0, results.getLong("testAddMeasurementLongZero"));
+ assertTrue(results.containsKey("testAddMeasurementLongPos"));
+ assertEquals(348573, results.getLong("testAddMeasurementLongPos"));
+ assertTrue(results.containsKey("testAddMeasurementLongNeg"));
+ assertEquals(-19354, results.getLong("testAddMeasurementLongNeg"));
+ }
+
+ @SmallTest
+ public void testAddMeasurementFloat() throws Exception {
+ MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
+ mPerfCollector.setPerformanceResultsWriter(writer);
+ mPerfCollector.startTiming("testAddMeasurementFloat");
+ mPerfCollector.addMeasurement("testAddMeasurementFloatZero", 0.0f);
+ mPerfCollector.addMeasurement("testAddMeasurementFloatPos", 348573.345f);
+ mPerfCollector.addMeasurement("testAddMeasurementFloatNeg", -19354.093f);
+ mPerfCollector.stopTiming("");
+
+ assertEquals("testAddMeasurementFloat", writer.timingLabel);
+ Bundle results = writer.timingResults;
+ assertEquals(4, results.size());
+ assertTrue(results.containsKey("testAddMeasurementFloatZero"));
+ assertEquals(0.0f, results.getFloat("testAddMeasurementFloatZero"));
+ assertTrue(results.containsKey("testAddMeasurementFloatPos"));
+ assertEquals(348573.345f, results.getFloat("testAddMeasurementFloatPos"));
+ assertTrue(results.containsKey("testAddMeasurementFloatNeg"));
+ assertEquals(-19354.093f, results.getFloat("testAddMeasurementFloatNeg"));
+ }
+
+ @SmallTest
+ public void testAddMeasurementString() throws Exception {
+ MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
+ mPerfCollector.setPerformanceResultsWriter(writer);
+ mPerfCollector.startTiming("testAddMeasurementString");
+ mPerfCollector.addMeasurement("testAddMeasurementStringNull", null);
+ mPerfCollector.addMeasurement("testAddMeasurementStringEmpty", "");
+ mPerfCollector.addMeasurement("testAddMeasurementStringNonEmpty", "Hello World");
+ mPerfCollector.stopTiming("");
+
+ assertEquals("testAddMeasurementString", writer.timingLabel);
+ Bundle results = writer.timingResults;
+ assertEquals(4, results.size());
+ assertTrue(results.containsKey("testAddMeasurementStringNull"));
+ assertNull(results.getString("testAddMeasurementStringNull"));
+ assertTrue(results.containsKey("testAddMeasurementStringEmpty"));
+ assertEquals("", results.getString("testAddMeasurementStringEmpty"));
+ assertTrue(results.containsKey("testAddMeasurementStringNonEmpty"));
+ assertEquals("Hello World", results.getString("testAddMeasurementStringNonEmpty"));
+ }
+
+ @SmallTest
public void testSimpleSequence() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
mPerfCollector.beginSnapshot("testSimpleSequence");
mPerfCollector.startTiming("testSimpleSequenceTiming");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration1");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration2");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration3");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration4");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing = mPerfCollector.stopTiming("iteration5");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
Bundle snapshot1 = mPerfCollector.endSnapshot();
Bundle snapshot2 = writer.snapshotResults;
- assertTrue(snapshot1.equals(snapshot2));
+ assertEqualsBundle(snapshot1, snapshot2);
verifySnapshotBundle(snapshot1);
ArrayList<String> labels = new ArrayList<String>();
@@ -193,60 +264,59 @@
verifyTimingBundle(timing, labels);
}
- // TODO: flaky test
- // @LargeTest
+ @SmallTest
public void testLongSequence() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
mPerfCollector.beginSnapshot("testLongSequence");
mPerfCollector.startTiming("testLongSequenceTiming1");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration1");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration2");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing1 = mPerfCollector.stopTiming("iteration3");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
mPerfCollector.startTiming("testLongSequenceTiming2");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration4");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration5");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing2 = mPerfCollector.stopTiming("iteration6");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
mPerfCollector.startTiming("testLongSequenceTiming3");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration7");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration8");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing3 = mPerfCollector.stopTiming("iteration9");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
mPerfCollector.startTiming("testLongSequenceTiming4");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration10");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration11");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing4 = mPerfCollector.stopTiming("iteration12");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
mPerfCollector.startTiming("testLongSequenceTiming5");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration13");
- sleepForRandomTinyPeriod();
+ workForRandomTinyPeriod();
mPerfCollector.addIteration("iteration14");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing5 = mPerfCollector.stopTiming("iteration15");
- sleepForRandomLongPeriod();
+ workForRandomLongPeriod();
Bundle snapshot1 = mPerfCollector.endSnapshot();
Bundle snapshot2 = writer.snapshotResults;
- assertTrue(snapshot1.equals(snapshot2));
+ assertEqualsBundle(snapshot1, snapshot2);
verifySnapshotBundle(snapshot1);
ArrayList<String> labels1 = new ArrayList<String>();
@@ -280,57 +350,53 @@
* Verify that snapshotting and timing do not interfere w/ each other,
* by staggering calls to snapshot and timing functions.
*/
- @LargeTest
+ @SmallTest
public void testOutOfOrderSequence() {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
mPerfCollector.startTiming("testOutOfOrderSequenceTiming");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
mPerfCollector.beginSnapshot("testOutOfOrderSequenceSnapshot");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle timing1 = mPerfCollector.stopTiming("timing1");
- sleepForRandomShortPeriod();
+ workForRandomShortPeriod();
Bundle snapshot1 = mPerfCollector.endSnapshot();
Bundle timing2 = writer.timingResults;
Bundle snapshot2 = writer.snapshotResults;
- assertTrue(snapshot1.equals(snapshot2));
+ assertEqualsBundle(snapshot1, snapshot2);
verifySnapshotBundle(snapshot1);
- assertTrue(timing1.equals(timing2));
+ assertEqualsBundle(timing1, timing2);
ArrayList<String> labels = new ArrayList<String>();
labels.add("timing1");
verifyTimingBundle(timing1, labels);
}
- private void sleepForRandomPeriod(int minDuration, int maxDuration) {
+ private void workForRandomPeriod(int minDuration, int maxDuration) {
Random random = new Random();
int period = minDuration + random.nextInt(maxDuration - minDuration);
- int slept = 0;
- // Generate random positive amount of work, so cpu time is measurable in
+ long start = Process.getElapsedCpuTime();
+ // Generate positive amount of work, so cpu time is measurable in
// milliseconds
- while (slept < period) {
- int step = random.nextInt(minDuration/5);
- try {
- Thread.sleep(step);
- } catch (InterruptedException e ) {
- // eat the exception
+ while (Process.getElapsedCpuTime() - start < period) {
+ for (int i = 0, temp = 0; i < 50; i++ ) {
+ temp += i;
}
- slept += step;
}
}
- private void sleepForRandomTinyPeriod() {
- sleepForRandomPeriod(25, 50);
+ private void workForRandomTinyPeriod() {
+ workForRandomPeriod(2, 5);
}
- private void sleepForRandomShortPeriod() {
- sleepForRandomPeriod(100, 250);
+ private void workForRandomShortPeriod() {
+ workForRandomPeriod(10, 25);
}
- private void sleepForRandomLongPeriod() {
- sleepForRandomPeriod(500, 1000);
+ private void workForRandomLongPeriod() {
+ workForRandomPeriod(50, 100);
}
private void verifySnapshotBundle(Bundle snapshot) {
@@ -411,6 +477,13 @@
}
}
+ private void assertEqualsBundle(Bundle b1, Bundle b2) {
+ assertEquals(b1.keySet(), b2.keySet());
+ for (String key : b1.keySet()) {
+ assertEquals(b1.get(key), b2.get(key));
+ }
+ }
+
private Object readPrivateField(String fieldName, Object object) throws Exception {
Field f = object.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
@@ -429,7 +502,7 @@
}
public void writeEndSnapshot(Bundle results) {
- snapshotResults = results;
+ snapshotResults.putAll(results);
}
public void writeStartTiming(String label) {
@@ -437,7 +510,19 @@
}
public void writeStopTiming(Bundle results) {
- timingResults = results;
+ timingResults.putAll(results);
+ }
+
+ public void writeMeasurement(String label, long value) {
+ timingResults.putLong(label, value);
+ }
+
+ public void writeMeasurement(String label, float value) {
+ timingResults.putFloat(label, value);
+ }
+
+ public void writeMeasurement(String label, String value) {
+ timingResults.putString(label, value);
}
}
}
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
index 9e2987a..db1262f 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
@@ -41,7 +41,7 @@
parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
InputStream input = this.getClass().getClassLoader().getResourceAsStream(
- "/com/android/layoutlib/testdata/layout1.xml");
+ "com/android/layoutlib/testdata/layout1.xml");
parser.setInput(input, null /*encoding*/);
assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
index 5314976..d5993db 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
@@ -13,7 +13,7 @@
@Override
protected void setUp() throws Exception {
URL url = this.getClass().getClassLoader().getResource(
- "/com/android/layoutlib/testdata/button.9.png");
+ "com/android/layoutlib/testdata/button.9.png");
mPatch = NinePatch.load(url, false /* convert */);
}