Merge "Document that degenerate lines wont be drawn" into jb-mr2-dev
diff --git a/api/current.txt b/api/current.txt
index a4b4992..3878aa1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9036,12 +9036,12 @@
ctor public Picture();
ctor public Picture(android.graphics.Picture);
method public android.graphics.Canvas beginRecording(int, int);
- method public static android.graphics.Picture createFromStream(java.io.InputStream);
+ method public static deprecated android.graphics.Picture createFromStream(java.io.InputStream);
method public void draw(android.graphics.Canvas);
method public void endRecording();
method public int getHeight();
method public int getWidth();
- method public void writeToStream(java.io.OutputStream);
+ method public deprecated void writeToStream(java.io.OutputStream);
}
public class PixelFormat {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 1bada67..d9846ec 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -25,6 +25,7 @@
import com.android.internal.annotations.GuardedBy;
import java.io.File;
+import java.io.IOException;
/**
* Provides access to environment variables.
@@ -36,12 +37,16 @@
private static final String ENV_EMULATED_STORAGE_SOURCE = "EMULATED_STORAGE_SOURCE";
private static final String ENV_EMULATED_STORAGE_TARGET = "EMULATED_STORAGE_TARGET";
private static final String ENV_MEDIA_STORAGE = "MEDIA_STORAGE";
+ private static final String ENV_ANDROID_ROOT = "ANDROID_ROOT";
/** {@hide} */
public static String DIRECTORY_ANDROID = "Android";
- private static final File ROOT_DIRECTORY
- = getDirectory("ANDROID_ROOT", "/system");
+ private static final File DIR_ANDROID_ROOT = getDirectory(ENV_ANDROID_ROOT, "/system");
+ private static final File DIR_MEDIA_STORAGE = getDirectory(ENV_MEDIA_STORAGE, "/data/media");
+
+ private static final String CANONCIAL_EMULATED_STORAGE_TARGET = getCanonicalPathOrNull(
+ ENV_EMULATED_STORAGE_TARGET);
private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
@@ -178,7 +183,7 @@
* Gets the Android root directory.
*/
public static File getRootDirectory() {
- return ROOT_DIRECTORY;
+ return DIR_ANDROID_ROOT;
}
/**
@@ -632,6 +637,19 @@
return path == null ? new File(defaultPath) : new File(path);
}
+ private static String getCanonicalPathOrNull(String variableName) {
+ String path = System.getenv(variableName);
+ if (path == null) {
+ return null;
+ }
+ try {
+ return new File(path).getCanonicalPath();
+ } catch (IOException e) {
+ Log.w(TAG, "Unable to resolve canonical path for " + path);
+ return null;
+ }
+ }
+
private static void throwIfSystem() {
if (Process.myUid() == Process.SYSTEM_UID) {
Log.wtf(TAG, "Static storage paths aren't available from AID_SYSTEM", new Throwable());
@@ -649,4 +667,40 @@
}
return cur;
}
+
+ /**
+ * If the given path exists on emulated external storage, return the
+ * translated backing path hosted on internal storage. This bypasses any
+ * emulation later, improving performance. This is <em>only</em> suitable
+ * for read-only access.
+ * <p>
+ * Returns original path if given path doesn't meet these criteria. Callers
+ * must hold {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}
+ * permission.
+ *
+ * @hide
+ */
+ public static File maybeTranslateEmulatedPathToInternal(File path) {
+ // Fast return if not emulated, or missing variables
+ if (!Environment.isExternalStorageEmulated()
+ || CANONCIAL_EMULATED_STORAGE_TARGET == null) {
+ return path;
+ }
+
+ try {
+ final String rawPath = path.getCanonicalPath();
+ if (rawPath.startsWith(CANONCIAL_EMULATED_STORAGE_TARGET)) {
+ final File internalPath = new File(DIR_MEDIA_STORAGE,
+ rawPath.substring(CANONCIAL_EMULATED_STORAGE_TARGET.length()));
+ if (internalPath.exists()) {
+ return internalPath;
+ }
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to resolve canonical path for " + path);
+ }
+
+ // Unable to translate to internal path; use original
+ return path;
+ }
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 0ab49ac..d901d0a 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1114,6 +1114,11 @@
* false. See also {@link #setDatabasePath} for how to correctly set up the
* database storage API.
*
+ * This setting is global in effect, across all WebView instances in a process.
+ * Note you should only modify this setting prior to making <b>any</b> WebView
+ * page load within a given process, as the WebView implementation may ignore
+ * changes to this setting after that point.
+ *
* @param flag true if the WebView should use the database storage API
*/
public synchronized void setDatabaseEnabled(boolean flag) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f3983187..175cbcb 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -208,8 +208,7 @@
* and default scaling is not applied to the web page; if the value is "1.5", then the device is
* considered a high density device (hdpi) and the page content is scaled 1.5x; if the
* value is "0.75", then the device is considered a low density device (ldpi) and the content is
- * scaled 0.75x. However, if you specify the {@code "target-densitydpi"} meta property
- * (discussed below), then you can stop this default scaling behavior.</li>
+ * scaled 0.75x.</li>
* <li>The {@code -webkit-device-pixel-ratio} CSS media query. Use this to specify the screen
* densities for which this style sheet is to be used. The corresponding value should be either
* "0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium
@@ -219,29 +218,6 @@
* <p>The {@code hdpi.css} stylesheet is only used for devices with a screen pixel ration of 1.5,
* which is the high density pixel ratio.</p>
* </li>
- * <li>The {@code target-densitydpi} property for the {@code viewport} meta tag. You can use
- * this to specify the target density for which the web page is designed, using the following
- * values:
- * <ul>
- * <li>{@code device-dpi} - Use the device's native dpi as the target dpi. Default scaling never
- * occurs.</li>
- * <li>{@code high-dpi} - Use hdpi as the target dpi. Medium and low density screens scale down
- * as appropriate.</li>
- * <li>{@code medium-dpi} - Use mdpi as the target dpi. High density screens scale up and
- * low density screens scale down. This is also the default behavior.</li>
- * <li>{@code low-dpi} - Use ldpi as the target dpi. Medium and high density screens scale up
- * as appropriate.</li>
- * <li><em>{@code <value>}</em> - Specify a dpi value to use as the target dpi (accepted
- * values are 70-400).</li>
- * </ul>
- * <p>Here's an example meta tag to specify the target density:</p>
- * <pre><meta name="viewport" content="target-densitydpi=device-dpi" /></pre></li>
- * </ul>
- * <p>If you want to modify your web page for different densities, by using the {@code
- * -webkit-device-pixel-ratio} CSS media query and/or the {@code
- * window.devicePixelRatio} DOM property, then you should set the {@code target-densitydpi} meta
- * property to {@code device-dpi}. This stops Android from performing scaling in your web page and
- * allows you to make the necessary adjustments for each density via CSS and JavaScript.</p>
*
* <h3>HTML5 Video support</h3>
*
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index 0c6b780..cf69a9d 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -19,6 +19,7 @@
import com.android.internal.R;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build;
@@ -44,7 +45,10 @@
}
public boolean showsOverflowMenuButton() {
- return !ViewConfiguration.get(mContext).hasPermanentMenuKey();
+ return !ViewConfiguration.get(mContext).hasPermanentMenuKey() ||
+ ((mContext.getResources().getConfiguration().uiMode &
+ Configuration.UI_MODE_TYPE_TELEVISION) ==
+ Configuration.UI_MODE_TYPE_TELEVISION);
}
public int getEmbeddedMenuWidthLimit() {
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index 0df8638..b4c4a1b 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -166,7 +166,7 @@
struct Stats stats;
memset(&stats, 0, sizeof(Stats));
- if (parseIfaceStats(NULL, &stats) == 0) {
+ if (parseIfaceStats(iface8.c_str(), &stats) == 0) {
return getStatsType(&stats, (StatsType) type);
} else {
return UNKNOWN;
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 91688db..9bb90f1 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1566,6 +1566,10 @@
* Save the canvas state, draw the picture, and restore the canvas state.
* This differs from picture.draw(canvas), which does not perform any
* save/restore.
+ *
+ * <p>
+ * <strong>Note:</strong> This forces the picture to internally call
+ * {@link Picture#endRecording} in order to prepare for playback.
*
* @param picture The picture to be drawn
*/
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index 997141d..71e02f6 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -20,13 +20,12 @@
import java.io.OutputStream;
/**
- * A picture records drawing calls (via the canvas returned by beginRecording)
- * and can then play them back (via picture.draw(canvas) or canvas.drawPicture).
- * The picture's contents can also be written to a stream, and then later
- * restored to a new picture (via writeToStream / createFromStream). For most
- * content (esp. text, lines, rectangles), drawing a sequence from a picture can
- * be faster than the equivalent API calls, since the picture performs its
- * playback without incurring any java-call overhead.
+ * A Picture records drawing calls (via the canvas returned by beginRecording)
+ * and can then play them back into Canvas (via {@link Picture#draw(Canvas)} or
+ * {@link Canvas#drawPicture(Picture)}).For most content (e.g. text, lines, rectangles),
+ * drawing a sequence from a picture can be faster than the equivalent API
+ * calls, since the picture performs its playback without incurring any
+ * method-call overhead.
*/
public class Picture {
private Canvas mRecordingCanvas;
@@ -39,6 +38,9 @@
private static final int WORKING_STREAM_STORAGE = 16 * 1024;
+ /**
+ * Creates an empty picture that is ready to record.
+ */
public Picture() {
this(nativeConstructor(0), false);
}
@@ -55,9 +57,10 @@
/**
* To record a picture, call beginRecording() and then draw into the Canvas
* that is returned. Nothing we appear on screen, but all of the draw
- * commands (e.g. drawRect(...)) will be recorded. To stop recording, call
- * endRecording(). At this point the Canvas that was returned must no longer
- * be referenced, and nothing should be drawn into it.
+ * commands (e.g. {@link Canvas#drawRect(Rect, Paint)}) will be recorded.
+ * To stop recording, call endRecording(). After endRecording() the Canvas
+ * that was returned must no longer be used, and nothing should be drawn
+ * into it.
*/
public Canvas beginRecording(int width, int height) {
int ni = nativeBeginRecording(mNativePicture, width, height);
@@ -68,8 +71,8 @@
/**
* Call endRecording when the picture is built. After this call, the picture
* may be drawn, but the canvas that was returned by beginRecording must not
- * be referenced anymore. This is automatically called if Picture.draw() or
- * Canvas.drawPicture() is called.
+ * be used anymore. This is automatically called if {@link Picture#draw}
+ * or {@link Canvas#drawPicture(Picture)} is called.
*/
public void endRecording() {
if (mRecordingCanvas != null) {
@@ -94,6 +97,10 @@
* Draw this picture on the canvas. The picture may have the side effect
* of changing the matrix and clip of the canvas.
*
+ * <p>
+ * <strong>Note:</strong> This forces the picture to internally call
+ * {@link Picture#endRecording()} in order to prepare for playback.
+ *
* @param canvas The picture is drawn to this canvas
*/
public void draw(Canvas canvas) {
@@ -105,26 +112,39 @@
/**
* Create a new picture (already recorded) from the data in the stream. This
- * data was generated by a previous call to writeToStream().
- *
+ * data was generated by a previous call to writeToStream(). Pictures that
+ * have been persisted across device restarts are not guaranteed to decode
+ * properly and are highly discouraged.
+ *
+ * <p>
* <strong>Note:</strong> a picture created from an input stream cannot be
* replayed on a hardware accelerated canvas.
*
- * @see #writeToStream(java.io.OutputStream)
+ * @see #writeToStream(java.io.OutputStream)
+ * @deprecated The recommended alternative is to not use writeToStream and
+ * instead draw the picture into a Bitmap from which you can persist it as
+ * raw or compressed pixels.
*/
+ @Deprecated
public static Picture createFromStream(InputStream stream) {
return new Picture(nativeCreateFromStream(stream, new byte[WORKING_STREAM_STORAGE]), true);
}
/**
* Write the picture contents to a stream. The data can be used to recreate
- * the picture in this or another process by calling createFromStream.
+ * the picture in this or another process by calling createFromStream(...)
+ * The resulting stream is NOT to be persisted across device restarts as
+ * there is no guarantee that the Picture can be successfully reconstructed.
*
+ * <p>
* <strong>Note:</strong> a picture created from an input stream cannot be
* replayed on a hardware accelerated canvas.
- *
- * @see #createFromStream(java.io.InputStream)
+ *
+ * @see #createFromStream(java.io.InputStream)
+ * @deprecated The recommended alternative is to draw the picture into a
+ * Bitmap from which you can persist it as raw or compressed pixels.
*/
+ @Deprecated
public void writeToStream(OutputStream stream) {
// do explicit check before calling the native method
if (stream == null) {
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 5befb95..a1cc2e8 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -50,9 +50,9 @@
Caches::Caches(): Singleton<Caches>(), mExtensions(Extensions::getInstance()), mInitialized(false) {
init();
initFont();
- initExtensions();
initConstraints();
initProperties();
+ initExtensions();
mDebugLevel = readDebugLevel();
ALOGD("Enabling debug mode %d", mDebugLevel);
@@ -103,15 +103,21 @@
void Caches::initExtensions() {
if (mExtensions.hasDebugMarker()) {
eventMark = glInsertEventMarkerEXT;
- startMark = glPushGroupMarkerEXT;
- endMark = glPopGroupMarkerEXT;
+ if ((drawDeferDisabled || drawReorderDisabled)) {
+ startMark = glPushGroupMarkerEXT;
+ endMark = glPopGroupMarkerEXT;
+ } else {
+ startMark = startMarkNull;
+ endMark = endMarkNull;
+ }
+
} else {
eventMark = eventMarkNull;
startMark = startMarkNull;
endMark = endMarkNull;
}
- if (mExtensions.hasDebugLabel()) {
+ if (mExtensions.hasDebugLabel() && (drawDeferDisabled || drawReorderDisabled)) {
setLabel = glLabelObjectEXT;
getLabel = glGetObjectLabelEXT;
} else {
@@ -164,6 +170,20 @@
debugStencilClip = kStencilHide;
}
+ if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) {
+ drawDeferDisabled = !strcasecmp(property, "true");
+ INIT_LOGD(" Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
+ } else {
+ INIT_LOGD(" Draw defer enabled");
+ }
+
+ if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) {
+ drawReorderDisabled = !strcasecmp(property, "true");
+ INIT_LOGD(" Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
+ } else {
+ INIT_LOGD(" Draw reorder enabled");
+ }
+
return (prevDebugLayersUpdates != debugLayersUpdates) ||
(prevDebugOverdraw != debugOverdraw) ||
(prevDebugStencilClip != debugStencilClip);
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index c35ad883..ca699d5 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -240,6 +240,9 @@
Program* currentProgram;
bool scissorEnabled;
+ bool drawDeferDisabled;
+ bool drawReorderDisabled;
+
// VBO to draw with
GLuint meshBuffer;
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index 8962964..a4e9950 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -146,6 +146,8 @@
if (isEmpty()) return status; // nothing to flush
DEFER_LOGD("--flushing");
+ renderer.eventMark("Flush");
+
DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers();
int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
int opCount = 0;
@@ -166,6 +168,7 @@
}
DEFER_LOGD("--flushed, drew %d batches (total %d ops)", mBatches.size(), opCount);
+
renderer.restoreToCount(restoreTo);
renderer.setDrawModifiers(restoreDrawModifiers);
clear();
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 9ecfb5a..4a72477 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -147,7 +147,8 @@
if (!renderer.storeDisplayState(state)) {
// op wasn't quick-rejected, so defer
- deferredList->add(this, renderer.disallowReorder());
+ deferredList->add(this, renderer.getCaches().drawReorderDisabled);
+ onDrawOpDeferred(renderer);
}
return DrawGlInfo::kStatusDone;
@@ -156,6 +157,9 @@
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
bool caching, int multipliedAlpha) = 0;
+ virtual void onDrawOpDeferred(OpenGLRenderer& renderer) {
+ }
+
// returns true if bounds exist
virtual bool getLocalBounds(Rect& localBounds) { return false; }
@@ -1081,6 +1085,12 @@
OP_LOG("Draw some text, %d bytes", mBytesCount);
}
+ virtual void onDrawOpDeferred(OpenGLRenderer& renderer) {
+ SkPaint* paint = getPaint(renderer);
+ FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
+ fontRenderer.precache(paint, mText, mCount, mat4::identity());
+ }
+
virtual DeferredDisplayList::OpBatchId getBatchId() {
return mPaint->getColor() == 0xff000000 ?
DeferredDisplayList::kOpBatch_Text :
@@ -1156,6 +1166,19 @@
mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom);
}
+ /*
+ * When this method is invoked the state field is initialized to have the
+ * final rendering state. We can thus use it to process data as it will be
+ * used at draw time.
+ */
+ virtual void onDrawOpDeferred(OpenGLRenderer& renderer) {
+ SkPaint* paint = getPaint(renderer);
+ FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
+ const bool pureTranslate = state.mMatrix.isPureTranslate();
+ fontRenderer.precache(paint, mText, mCount,
+ pureTranslate ? mat4::identity() : state.mMatrix);
+ }
+
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
bool caching, int multipliedAlpha) {
return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 16218fa..b011443 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -403,11 +403,7 @@
DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
hOffset, vOffset, paint);
- if (addDrawOp(op)) {
- // precache if draw operation is visible
- FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
- fontRenderer.precache(paint, text, count, mat4::identity());
- }
+ addDrawOp(op);
return DrawGlInfo::kStatusDone;
}
@@ -420,11 +416,7 @@
paint = refPaint(paint);
DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
- if (addDrawOp(op)) {
- // precache if draw operation is visible
- FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
- fontRenderer.precache(paint, text, count, mat4::identity());
- }
+ addDrawOp(op);
return DrawGlInfo::kStatusDone;
}
@@ -439,13 +431,7 @@
paint = refPaint(paint);
DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length);
- if (addDrawOp(op)) {
- // precache if draw operation is visible
- FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
- const bool pureTranslate = mSnapshot->transform->isPureTranslate();
- fontRenderer.precache(paint, text, count,
- pureTranslate ? mat4::identity() : *mSnapshot->transform);
- }
+ addDrawOp(op);
return DrawGlInfo::kStatusDone;
}
@@ -515,17 +501,15 @@
addOpInternal(op);
}
-bool DisplayListRenderer::addDrawOp(DrawOp* op) {
- bool rejected = false;
+void DisplayListRenderer::addDrawOp(DrawOp* op) {
Rect localBounds;
if (op->getLocalBounds(localBounds)) {
- rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
+ bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
localBounds.right, localBounds.bottom);
op->setQuickRejected(rejected);
}
mHasDrawOps = true;
addOpInternal(op);
- return !rejected;
}
}; // namespace uirenderer
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index bff3b97..38619bf 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -195,7 +195,7 @@
LinearAllocator& alloc() { return mDisplayListData->allocator; }
void addStateOp(StateOp* op);
- bool addDrawOp(DrawOp* op); // returns true if op not rejected
+ void addDrawOp(DrawOp* op);
void addOpInternal(DisplayListOp* op) {
insertRestoreToCount();
insertTranslate();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7e9734f..ff6f332 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -122,8 +122,6 @@
mFirstSnapshot = new Snapshot;
mScissorOptimizationDisabled = false;
- mDrawDeferDisabled = false;
- mDrawReorderDisabled = false;
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -140,20 +138,6 @@
} else {
INIT_LOGD(" Scissor optimization enabled");
}
-
- if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) {
- mDrawDeferDisabled = !strcasecmp(property, "true");
- INIT_LOGD(" Draw defer %s", mDrawDeferDisabled ? "disabled" : "enabled");
- } else {
- INIT_LOGD(" Draw defer enabled");
- }
-
- if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) {
- mDrawReorderDisabled = !strcasecmp(property, "true");
- INIT_LOGD(" Draw reorder %s", mDrawReorderDisabled ? "disabled" : "enabled");
- } else {
- INIT_LOGD(" Draw reorder enabled");
- }
}
///////////////////////////////////////////////////////////////////////////////
@@ -462,6 +446,10 @@
// Debug
///////////////////////////////////////////////////////////////////////////////
+void OpenGLRenderer::eventMark(const char* name) const {
+ mCaches.eventMark(0, name);
+}
+
void OpenGLRenderer::startMark(const char* name) const {
mCaches.startMark(0, name);
}
@@ -1815,7 +1803,7 @@
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
- if (CC_UNLIKELY(mDrawDeferDisabled)) {
+ if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
return displayList->replay(*this, dirty, flags, 0);
}
@@ -2710,7 +2698,7 @@
setupDrawShaderUniforms(!isPerspective);
setupDrawTextGammaUniforms();
- const Rect* clip = mSnapshot->hasPerspectiveTransform() ? NULL : mSnapshot->clipRect;
+ const Rect* clip = isPerspective ? NULL : mSnapshot->clipRect;
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
const bool hasActiveLayer = hasLayer();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index cfad593..1bfd3c0 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -270,8 +270,6 @@
(mSnapshot->flags & Snapshot::kFlagFboTarget); // ensure we're not in a layer
}
- bool disallowReorder() { return mDrawReorderDisabled; }
-
bool storeDisplayState(DeferredDisplayState& state);
void restoreDisplayState(const DeferredDisplayState& state);
@@ -282,6 +280,10 @@
return mSnapshot->transform->isSimple();
}
+ Caches& getCaches() {
+ return mCaches;
+ }
+
/**
* Sets the alpha on the current snapshot. This alpha value will be modulated
* with other alpha values when drawing primitives.
@@ -291,6 +293,11 @@
}
/**
+ * Inserts a named event marker in the stream of GL commands.
+ */
+ void eventMark(const char* name) const;
+
+ /**
* Inserts a named group marker in the stream of GL commands. This marker
* can be used by tools to group commands into logical groups. A call to
* this method must always be followed later on by a call to endMark().
@@ -439,10 +446,6 @@
return false;
}
- Caches& getCaches() {
- return mCaches;
- }
-
private:
/**
* Discards the content of the framebuffer if supported by the driver.
@@ -957,8 +960,6 @@
// See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in
// Properties.h
bool mScissorOptimizationDisabled;
- bool mDrawDeferDisabled;
- bool mDrawReorderDisabled;
// No-ops start/endTiling when set
bool mSuppressTiling;
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index d48b612..bf522b7 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -57,6 +57,9 @@
mLookupTransform[SkMatrix::kMScaleY] = matrix.data[mat4::kScaleY];
mLookupTransform[SkMatrix::kMSkewX] = matrix.data[mat4::kSkewX];
mLookupTransform[SkMatrix::kMSkewY] = matrix.data[mat4::kSkewY];
+ if (!mLookupTransform.invert(&mInverseLookupTransform)) {
+ ALOGW("Could not query the inverse lookup transform for this font");
+ }
}
Font::~Font() {
@@ -184,18 +187,13 @@
void Font::drawCachedGlyphPerspective(CachedGlyphInfo* glyph, int x, int y,
uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
- SkMatrix i;
- if (!mDescription.mLookupTransform.invert(&i)) {
- return;
- }
-
SkPoint p[4];
- p[0].set(glyph->mBitmapLeft, glyph->mBitmapTop + glyph->mBitmapHeight);
- p[1].set(glyph->mBitmapLeft + glyph->mBitmapWidth, glyph->mBitmapTop + glyph->mBitmapHeight);
- p[2].set(glyph->mBitmapLeft + glyph->mBitmapWidth, glyph->mBitmapTop);
- p[3].set(glyph->mBitmapLeft, glyph->mBitmapTop);
+ p[0].iset(glyph->mBitmapLeft, glyph->mBitmapTop + glyph->mBitmapHeight);
+ p[1].iset(glyph->mBitmapLeft + glyph->mBitmapWidth, glyph->mBitmapTop + glyph->mBitmapHeight);
+ p[2].iset(glyph->mBitmapLeft + glyph->mBitmapWidth, glyph->mBitmapTop);
+ p[3].iset(glyph->mBitmapLeft, glyph->mBitmapTop);
- i.mapPoints(p, 4);
+ mDescription.mInverseLookupTransform.mapPoints(p, 4);
p[0].offset(x, y);
p[1].offset(x, y);
@@ -208,10 +206,10 @@
float v2 = glyph->mBitmapMaxV;
mState->appendRotatedMeshQuad(
- p[0].fX, p[0].fY, u1, v2,
- p[1].fX, p[1].fY, u2, v2,
- p[2].fX, p[2].fY, u2, v1,
- p[3].fX, p[3].fY, u1, v1, glyph->mCacheTexture);
+ p[0].x(), p[0].y(), u1, v2,
+ p[1].x(), p[1].y(), u2, v2,
+ p[2].x(), p[2].y(), u2, v1,
+ p[3].x(), p[3].y(), u1, v1, glyph->mCacheTexture);
}
void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
@@ -265,14 +263,14 @@
const float v2 = glyph->mBitmapMaxV;
mState->appendRotatedMeshQuad(
- position->fX + destination[0].fX,
- position->fY + destination[0].fY, u1, v2,
- position->fX + destination[1].fX,
- position->fY + destination[1].fY, u2, v2,
- position->fX + destination[2].fX,
- position->fY + destination[2].fY, u2, v1,
- position->fX + destination[3].fX,
- position->fY + destination[3].fY, u1, v1,
+ position->x() + destination[0].x(),
+ position->y() + destination[0].y(), u1, v2,
+ position->x() + destination[1].x(),
+ position->y() + destination[1].y(), u2, v2,
+ position->x() + destination[2].x(),
+ position->y() + destination[2].y(), u2, v1,
+ position->x() + destination[3].x(),
+ position->y() + destination[3].y(), u1, v1,
glyph->mCacheTexture);
}
@@ -284,7 +282,8 @@
// Is the glyph still in texture cache?
if (!cachedGlyph->mIsValid) {
- const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit, &mDescription.mLookupTransform);
+ const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit,
+ &mDescription.mLookupTransform);
updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
}
} else {
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index 542b552..b2382f4 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -70,6 +70,7 @@
float mStrokeWidth;
bool mAntiAliasing;
SkMatrix mLookupTransform;
+ SkMatrix mInverseLookupTransform;
};
~Font();
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index 3dcd232..57c87e4 100644
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -7,6 +7,8 @@
<uses-permission android:name="android.permission.ASEC_DESTROY"/>
<uses-permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <!-- Used to improve MeasureUtils performance on emulated storage -->
+ <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
<uses-permission android:name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" />
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 731a09c..de77cac 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -16,16 +16,12 @@
package com.android.defcontainer;
-import com.android.internal.app.IMediaContainerService;
-import com.android.internal.content.NativeLibraryHelper;
-import com.android.internal.content.PackageHelper;
-
import android.app.IntentService;
import android.content.Intent;
-import android.content.pm.MacAuthenticatedInputStream;
import android.content.pm.ContainerEncryptionParams;
import android.content.pm.IPackageManager;
import android.content.pm.LimitedLengthInputStream;
+import android.content.pm.MacAuthenticatedInputStream;
import android.content.pm.PackageCleanItem;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
@@ -43,10 +39,16 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StatFs;
+import android.os.SystemClock;
import android.provider.Settings;
import android.util.DisplayMetrics;
+import android.util.Log;
import android.util.Slog;
+import com.android.internal.app.IMediaContainerService;
+import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.content.PackageHelper;
+
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -228,9 +230,10 @@
public long calculateDirectorySize(String path) throws RemoteException {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- final File directory = new File(path);
- if (directory.exists() && directory.isDirectory()) {
- return MeasurementUtils.measureDirectory(path);
+ final File dir = Environment.maybeTranslateEmulatedPathToInternal(new File(path));
+ if (dir.exists() && dir.isDirectory()) {
+ final String targetPath = dir.getAbsolutePath();
+ return MeasurementUtils.measureDirectory(targetPath);
} else {
return 0L;
}
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index e2d9d6e..f337600 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -46,6 +46,7 @@
<LinearLayout android:id="@+id/recents_linear_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_gravity="left"
android:orientation="horizontal">
</LinearLayout>
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a766bad..d8bcf2cd 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7419,29 +7419,63 @@
SystemProperties.set("ctl.start", "bugreport");
}
+ public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
+ return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
+ }
+
+ public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
+ if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
+ return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
+ }
+ return KEY_DISPATCHING_TIMEOUT;
+ }
+
+
public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.FILTER_EVENTS);
}
-
ProcessRecord proc;
-
- // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
+ long timeout;
synchronized (this) {
synchronized (mPidsSelfLocked) {
proc = mPidsSelfLocked.get(pid);
}
- if (proc != null) {
+ timeout = getInputDispatchingTimeoutLocked(proc);
+ }
+
+ if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
+ return -1;
+ }
+
+ return timeout;
+ }
+
+ /**
+ * Handle input dispatching timeouts.
+ * Returns whether input dispatching should be aborted or not.
+ */
+ public boolean inputDispatchingTimedOut(final ProcessRecord proc,
+ final ActivityRecord activity, final ActivityRecord parent,
+ final boolean aboveSystem) {
+ if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission "
+ + android.Manifest.permission.FILTER_EVENTS);
+ }
+
+ if (proc != null) {
+ synchronized (this) {
if (proc.debugging) {
- return -1;
+ return false;
}
if (mDidDexOpt) {
// Give more time since we were dexopting.
mDidDexOpt = false;
- return -1;
+ return false;
}
if (proc.instrumentationClass != null) {
@@ -7449,25 +7483,18 @@
info.putString("shortMsg", "keyDispatchingTimedOut");
info.putString("longMsg", "Timed out while dispatching key event");
finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
- proc = null;
+ return true;
}
}
- }
-
- if (proc != null) {
- final ProcessRecord pr = proc;
mHandler.post(new Runnable() {
@Override
public void run() {
- appNotResponding(pr, null, null, aboveSystem, "keyDispatchingTimedOut");
+ appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
}
});
- if (proc.instrumentationClass != null || proc.usingWrapper) {
- return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
- }
}
- return KEY_DISPATCHING_TIMEOUT;
+ return true;
}
public Bundle getTopActivityExtras(int requestType) {
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index cde17c9..054d213 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -867,51 +867,20 @@
}
public boolean keyDispatchingTimedOut() {
- // TODO: Unify this code with ActivityManagerService.inputDispatchingTimedOut().
ActivityRecord r;
- ProcessRecord anrApp = null;
+ ProcessRecord anrApp;
synchronized(service) {
r = getWaitingHistoryRecordLocked();
- if (r != null && r.app != null) {
- if (r.app.debugging) {
- return false;
- }
-
- if (service.mDidDexOpt) {
- // Give more time since we were dexopting.
- service.mDidDexOpt = false;
- return false;
- }
-
- if (r.app.instrumentationClass == null) {
- anrApp = r.app;
- } else {
- Bundle info = new Bundle();
- info.putString("shortMsg", "keyDispatchingTimedOut");
- info.putString("longMsg", "Timed out while dispatching key event");
- service.finishInstrumentationLocked(
- r.app, Activity.RESULT_CANCELED, info);
- }
- }
+ anrApp = r != null ? r.app : null;
}
-
- if (anrApp != null) {
- service.appNotResponding(anrApp, r, this, false, "keyDispatchingTimedOut");
- }
-
- return true;
+ return service.inputDispatchingTimedOut(anrApp, r, this, false);
}
/** Returns the key dispatching timeout for this application token. */
public long getKeyDispatchingTimeout() {
synchronized(service) {
ActivityRecord r = getWaitingHistoryRecordLocked();
- if (r != null && r.app != null
- && (r.app.instrumentationClass != null || r.app.usingWrapper)) {
- return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
- }
-
- return ActivityManagerService.KEY_DISPATCHING_TIMEOUT;
+ return ActivityManagerService.getInputDispatchingTimeoutLocked(r);
}
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 28f6bb2..900a38a 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1378,7 +1378,7 @@
private static final String FLAGS_STR = "flags=";
private static final String SSID_STR = "ssid=";
private static final String DELIMITER_STR = "====";
- private static final int SCAN_BUF_RANGE = 3900;
+ private static final String END_STR = "####";
/**
* Format:
@@ -1417,11 +1417,12 @@
if (TextUtils.isEmpty(tmpResults)) break;
scanResultsBuf.append(tmpResults);
scanResultsBuf.append("\n");
- if (tmpResults.length() < SCAN_BUF_RANGE) break;
String[] lines = tmpResults.split("\n");
sid = -1;
for (int i=lines.length - 1; i >= 0; i--) {
- if (lines[i].startsWith(ID_STR)) {
+ if (lines[i].startsWith(END_STR)) {
+ break;
+ } else if (lines[i].startsWith(ID_STR)) {
try {
sid = Integer.parseInt(lines[i].substring(ID_STR.length())) + 1;
} catch (NumberFormatException e) {
@@ -1472,7 +1473,7 @@
} else if (line.startsWith(SSID_STR)) {
wifiSsid = WifiSsid.createFromAsciiEncoded(
line.substring(SSID_STR.length()));
- } else if (line.startsWith(DELIMITER_STR)) {
+ } else if (line.startsWith(DELIMITER_STR) || line.startsWith(END_STR)) {
if (bssid != null) {
String ssid = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
String key = bssid + ssid;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index b6bbfc4..1ba991e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -155,6 +155,7 @@
/** copy constructor */
public WifiP2pWfdInfo(WifiP2pWfdInfo source) {
if (source != null) {
+ mWfdEnabled = source.mWfdEnabled;
mDeviceInfo = source.mDeviceInfo;
mCtrlPort = source.mCtrlPort;
mMaxThroughput = source.mMaxThroughput;