summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt10
-rw-r--r--core/java/android/app/Activity.java6
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java14
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java16
-rw-r--r--core/java/android/print/PrintAttributes.java12
-rw-r--r--core/java/android/print/PrintDocumentAdapter.java2
-rw-r--r--core/java/android/print/PrintJob.java1
-rw-r--r--core/java/android/printservice/PrintService.java1
-rw-r--r--core/java/android/text/AndroidBidi.java3
-rw-r--r--core/java/android/transition/TextChange.java9
-rw-r--r--core/java/android/view/View.java31
-rw-r--r--core/java/android/webkit/WebView.java45
-rw-r--r--core/java/android/webkit/WebViewClassic.java8
-rw-r--r--core/java/android/webkit/WebViewProvider.java8
-rw-r--r--core/res/res/values/config.xml12
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--libs/hwui/DeferredDisplayList.cpp131
-rw-r--r--libs/hwui/DeferredDisplayList.h48
-rw-r--r--libs/hwui/DisplayList.h4
-rw-r--r--libs/hwui/DisplayListOp.h129
-rw-r--r--libs/hwui/DisplayListRenderer.cpp9
-rw-r--r--libs/hwui/OpenGLRenderer.h17
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java2
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java316
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java24
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java3
-rw-r--r--services/java/com/android/server/location/FlpHardwareProvider.java16
-rw-r--r--services/java/com/android/server/location/GpsLocationProvider.java17
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java100
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java58
-rw-r--r--services/java/com/android/server/print/RemotePrintService.java151
-rw-r--r--services/java/com/android/server/print/RemotePrintSpooler.java3
-rw-r--r--services/java/com/android/server/print/UserState.java204
-rw-r--r--services/java/com/android/server/wifi/WifiService.java49
-rw-r--r--wifi/java/android/net/wifi/WifiConfigStore.java46
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java14
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java7
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java17
38 files changed, 1003 insertions, 542 deletions
diff --git a/api/current.txt b/api/current.txt
index 35f5f09..529ffe2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2725,8 +2725,6 @@ package android.app {
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void closeContextMenu();
method public void closeOptionsMenu();
- method public void convertFromTranslucent();
- method public void convertToTranslucent(android.app.Activity.TranslucentConversionListener);
method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
method public final deprecated void dismissDialog(int);
method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
@@ -2912,10 +2910,6 @@ package android.app {
field public static final int RESULT_OK = -1; // 0xffffffff
}
- public static abstract interface Activity.TranslucentConversionListener {
- method public abstract void onTranslucentConversionComplete(boolean);
- }
-
public deprecated class ActivityGroup extends android.app.Activity {
ctor public ActivityGroup();
ctor public ActivityGroup(boolean);
@@ -10973,6 +10967,8 @@ package android.hardware.camera2 {
field public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2; // 0x2
field public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0; // 0x0
field public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1; // 0x1
+ field public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0; // 0x0
+ field public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1; // 0x1
field public static final int STATISTICS_SCENE_FLICKER_50HZ = 1; // 0x1
field public static final int STATISTICS_SCENE_FLICKER_60HZ = 2; // 0x2
field public static final int STATISTICS_SCENE_FLICKER_NONE = 0; // 0x0
@@ -11078,6 +11074,7 @@ package android.hardware.camera2 {
field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+ field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED;
@@ -30164,6 +30161,7 @@ package android.webkit {
method public void clearSslPreferences();
method public deprecated void clearView();
method public android.webkit.WebBackForwardList copyBackForwardList();
+ method public android.print.PrintDocumentAdapter createPrintDocumentAdapter();
method public void destroy();
method public void documentHasImages(android.os.Message);
method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 57686a4..a38fbbf 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4907,6 +4907,8 @@ public class Activity extends ContextThemeWrapper
*
* @see #convertToTranslucent(TranslucentConversionListener)
* @see TranslucentConversionListener
+ *
+ * @hide
*/
public void convertFromTranslucent() {
try {
@@ -4937,6 +4939,8 @@ public class Activity extends ContextThemeWrapper
*
* @see #convertFromTranslucent()
* @see TranslucentConversionListener
+ *
+ * @hide
*/
public void convertToTranslucent(TranslucentConversionListener callback) {
try {
@@ -5441,6 +5445,8 @@ public class Activity extends ContextThemeWrapper
* opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn
* translucent again following a call to {@link
* Activity#convertToTranslucent(TranslucentConversionListener)}.
+ *
+ * @hide
*/
public interface TranslucentConversionListener {
/**
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 361e7de..ec23f08 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -874,6 +874,20 @@ public abstract class CameraMetadata {
public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
//
+ // Enumeration values for CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+ //
+
+ /**
+ * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+ */
+ public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0;
+
+ /**
+ * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+ */
+ public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1;
+
+ //
// Enumeration values for CaptureRequest#TONEMAP_MODE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index c3a636d..4608ab9 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -957,6 +957,22 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
/**
* <p>
+ * Whether the HAL needs to output the lens
+ * shading map in output result metadata
+ * </p>
+ * <p>
+ * When set to ON,
+ * android.statistics.lensShadingMap must be provided in
+ * the output result metdata.
+ * </p>
+ * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
+ * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
+ */
+ public static final Key<Integer> STATISTICS_LENS_SHADING_MAP_MODE =
+ new Key<Integer>("android.statistics.lensShadingMapMode", int.class);
+
+ /**
+ * <p>
* Table mapping blue input values to output
* values
* </p>
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index b1e427e..a1ffa8c 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -226,6 +226,12 @@ public final class PrintAttributes implements Parcelable {
StringBuilder builder = new StringBuilder();
builder.append("PrintAttributes{");
builder.append("mediaSize: ").append(mMediaSize);
+ if (mMediaSize != null) {
+ builder.append(", orientation: ").append(mMediaSize.isPortrait()
+ ? "portrait" : "landscape");
+ } else {
+ builder.append(", orientation: ").append("null");
+ }
builder.append(", resolution: ").append(mResolution);
builder.append(", margins: ").append(mMargins);
builder.append(", colorMode: ").append(colorModeToString(mColorMode));
@@ -880,12 +886,6 @@ public final class PrintAttributes implements Parcelable {
* @param bottomMils The bottom margin in mils (thousands of an inch).
*/
public Margins(int leftMils, int topMils, int rightMils, int bottomMils) {
- if (leftMils > rightMils) {
- throw new IllegalArgumentException("leftMils cannot be less than rightMils.");
- }
- if (topMils > bottomMils) {
- throw new IllegalArgumentException("topMils cannot be less than bottomMils.");
- }
mTopMils = topMils;
mLeftMils = leftMils;
mRightMils = rightMils;
diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java
index c81ca95..8ac34c1 100644
--- a/core/java/android/print/PrintDocumentAdapter.java
+++ b/core/java/android/print/PrintDocumentAdapter.java
@@ -20,8 +20,6 @@ import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
-import java.util.List;
-
/**
* Base class that provides the content of a document to be printed.
*
diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java
index de28bd3..42bea6d 100644
--- a/core/java/android/print/PrintJob.java
+++ b/core/java/android/print/PrintJob.java
@@ -16,7 +16,6 @@
package android.print;
-
/**
* This class represents a print job from the perspective of
* an application.
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
index 0ffc40a..012e76a 100644
--- a/core/java/android/printservice/PrintService.java
+++ b/core/java/android/printservice/PrintService.java
@@ -20,7 +20,6 @@ import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
diff --git a/core/java/android/text/AndroidBidi.java b/core/java/android/text/AndroidBidi.java
index eacd40d..b1c07f5 100644
--- a/core/java/android/text/AndroidBidi.java
+++ b/core/java/android/text/AndroidBidi.java
@@ -60,6 +60,9 @@ import android.text.Layout.Directions;
*/
public static Directions directions(int dir, byte[] levels, int lstart,
char[] chars, int cstart, int len) {
+ if (len == 0) {
+ return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+ }
int baseLevel = dir == Layout.DIR_LEFT_TO_RIGHT ? 0 : 1;
int curLevel = levels[lstart];
diff --git a/core/java/android/transition/TextChange.java b/core/java/android/transition/TextChange.java
index 4f14d46..0b1e4e1 100644
--- a/core/java/android/transition/TextChange.java
+++ b/core/java/android/transition/TextChange.java
@@ -137,14 +137,17 @@ public class TextChange extends Transition {
@Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
- if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
+ if (startValues == null || endValues == null ||
+ !(startValues.view instanceof TextView) || !(endValues.view instanceof TextView)) {
return null;
}
final TextView view = (TextView) endValues.view;
Map<String, Object> startVals = startValues.values;
Map<String, Object> endVals = endValues.values;
- final CharSequence startText = (CharSequence) startVals.get(PROPNAME_TEXT);
- final CharSequence endText = (CharSequence) endVals.get(PROPNAME_TEXT);
+ final CharSequence startText = startVals.get(PROPNAME_TEXT) != null ?
+ (CharSequence) startVals.get(PROPNAME_TEXT) : "";
+ final CharSequence endText = endVals.get(PROPNAME_TEXT) != null ?
+ (CharSequence) endVals.get(PROPNAME_TEXT) : "";
if (!startText.equals(endText)) {
view.setText(startText);
Animator anim;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 30531ed..8f8f9c6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8008,7 +8008,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean result = false;
- if (KeyEvent.isConfirmKey(event.getKeyCode())) {
+ if (KeyEvent.isConfirmKey(keyCode)) {
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
return true;
}
@@ -8050,28 +8050,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param event The KeyEvent object that defines the button action.
*/
public boolean onKeyUp(int keyCode, KeyEvent event) {
- boolean result = false;
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_ENTER: {
- if ((mViewFlags & ENABLED_MASK) == DISABLED) {
- return true;
- }
- if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
- setPressed(false);
-
- if (!mHasPerformedLongPress) {
- // This is a tap, so remove the longpress check
- removeLongPressCallback();
+ if (KeyEvent.isConfirmKey(keyCode)) {
+ if ((mViewFlags & ENABLED_MASK) == DISABLED) {
+ return true;
+ }
+ if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
+ setPressed(false);
- result = performClick();
- }
+ if (!mHasPerformedLongPress) {
+ // This is a tap, so remove the longpress check
+ removeLongPressCallback();
+ return performClick();
}
- break;
}
}
- return result;
+ return false;
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 8fc3ce3..15331dc 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -31,9 +31,8 @@ import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Looper;
import android.os.Message;
-import android.os.ParcelFileDescriptor;
import android.os.StrictMode;
-import android.print.PrintAttributes;
+import android.print.PrintDocumentAdapter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
@@ -1069,41 +1068,21 @@ public class WebView extends AbsoluteLayout
}
/**
- * Exports the contents of this Webview as PDF. Only supported for API levels
+ * Creates a PrintDocumentAdapter that provides the content of this Webview for printing.
+ * Only supported for API levels
* {@link android.os.Build.VERSION_CODES#KITKAT} and above.
*
- * TODO(sgurun) the parameter list is stale. Fix it before unhiding.
- *
- * @param fd The FileDescriptor to export the PDF contents to. Cannot be null.
- * @param width The page width. Should be larger than 0.
- * @param height The page height. Should be larger than 0.
- * @param resultCallback A callback to be invoked when the PDF content is exported.
- * A true indicates success, and a false failure. Cannot be null.
- * @param cancellationSignal Signal for cancelling the PDF conversion request. Must not
- * be null.
- *
- * The PDF conversion is done asynchronously and the PDF output is written to the provided
- * file descriptor. The caller should not close the file descriptor until the resultCallback
- * is called, indicating PDF conversion is complete. Webview will never close the file
- * descriptor.
- * Limitations: Webview cannot be drawn during the PDF export so the application is
- * recommended to take it offscreen, or putting in a layer with an overlaid progress
- * UI / spinner.
- *
- * If the caller cancels the task using the cancellationSignal, the cancellation will be
- * acked using the resultCallback signal.
- *
- * Throws an exception if an IO error occurs accessing the file descriptor.
- *
- * TODO(sgurun) margins, explain the units, make it public.
- * @hide
+ * The adapter works by converting the Webview contents to a PDF stream. The Webview cannot
+ * be drawn during the conversion process - any such draws are undefined. It is recommended
+ * to use a dedicated off screen Webview for the printing. If necessary, an application may
+ * temporarily hide a visible WebView by using a custom PrintDocumentAdapter instance
+ * wrapped around the object returned and observing the onStart and onFinish methods. See
+ * {@link android.print.PrintDocumentAdapter} for more information.
*/
- public void exportToPdf(ParcelFileDescriptor fd, PrintAttributes attributes,
- ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
- throws java.io.IOException {
+ public PrintDocumentAdapter createPrintDocumentAdapter() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "exportToPdf");
- mProvider.exportToPdf(fd, attributes, resultCallback, cancellationSignal);
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "createPrintDocumentAdapter");
+ return mProvider.createPrintDocumentAdapter();
}
/**
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 3f22d53..e82ce30 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -62,7 +62,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
-import android.print.PrintAttributes;
+import android.print.PrintDocumentAdapter;
import android.security.KeyChain;
import android.text.Editable;
import android.text.InputType;
@@ -2894,12 +2894,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
/**
- * See {@link WebView#exportToPdf()}
+ * See {@link WebView#createPrintDocumentAdapter()}
*/
@Override
- public void exportToPdf(android.os.ParcelFileDescriptor fd, PrintAttributes attributes,
- ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
- throws java.io.IOException {
+ public PrintDocumentAdapter createPrintDocumentAdapter() {
// K-only API not implemented in WebViewClassic.
throw new IllegalStateException("This API not supported on Android 4.3 and earlier");
}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index d625d8a..696aad4 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -25,10 +25,8 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.http.SslCertificate;
import android.os.Bundle;
-import android.os.CancellationSignal;
import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.print.PrintAttributes;
+import android.print.PrintDocumentAdapter;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -149,9 +147,7 @@ public interface WebViewProvider {
public Picture capturePicture();
- public void exportToPdf(ParcelFileDescriptor fd, PrintAttributes attributes,
- ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
- throws java.io.IOException;
+ public PrintDocumentAdapter createPrintDocumentAdapter();
public float getScale();
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ab95d40..d4b834a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -450,6 +450,13 @@
The default is false. -->
<bool name="config_lidControlsSleep">false</bool>
+ <!-- Indicate whether to allow the device to suspend when the screen is off
+ due to the proximity sensor. This resource should only be set to true
+ if the sensor HAL correctly handles the proximity sensor as a wake-up source.
+ Otherwise, the device may fail to wake out of suspend reliably.
+ The default is false. -->
+ <bool name="config_suspendWhenScreenOffDueToProximity">false</bool>
+
<!-- Control the behavior when the user long presses the power button.
0 - Nothing
1 - Global actions menu
@@ -793,6 +800,11 @@
<!-- 2 means give warning -->
<integer name="config_datause_notification_type">2</integer>
+ <!-- If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 this is the value
+ that should be used instead. A value of RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means
+ there is no replacement value and VoLTE is assumed to be supported -->
+ <integer name="config_volte_replacement_rat">0</integer>
+
<!-- Flag indicating whether the current device is "voice capable".
If true, this means that the device supports circuit-switched
(i.e. voice) phone calls over the telephony network, and is
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 39e7127..44891a8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -260,6 +260,7 @@
<java-symbol type="bool" name="config_sip_wifi_only" />
<java-symbol type="bool" name="config_sms_capable" />
<java-symbol type="bool" name="config_sms_utf8_support" />
+ <java-symbol type="bool" name="config_suspendWhenScreenOffDueToProximity" />
<java-symbol type="bool" name="config_swipeDisambiguation" />
<java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
<java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
@@ -313,6 +314,7 @@
<java-symbol type="integer" name="config_multiuserMaximumUsers" />
<java-symbol type="integer" name="config_safe_media_volume_index" />
<java-symbol type="integer" name="config_mobile_mtu" />
+ <java-symbol type="integer" name="config_volte_replacement_rat"/>
<java-symbol type="color" name="tab_indicator_text_v4" />
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index 7ce15c5..fd9257a 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -66,23 +66,23 @@ public:
virtual ~DrawBatch() { mOps.clear(); }
- virtual void add(DrawOp* op, bool opaqueOverBounds) {
+ virtual void add(DrawOp* op, const DeferredDisplayState* state, bool opaqueOverBounds) {
// NOTE: ignore empty bounds special case, since we don't merge across those ops
- mBounds.unionWith(op->state.mBounds);
+ mBounds.unionWith(state->mBounds);
mAllOpsOpaque &= opaqueOverBounds;
- mOps.add(op);
+ mOps.add(OpStatePair(op, state));
}
- bool intersects(Rect& rect) {
+ bool intersects(const Rect& rect) {
if (!rect.intersects(mBounds)) return false;
for (unsigned int i = 0; i < mOps.size(); i++) {
- if (rect.intersects(mOps[i]->state.mBounds)) {
+ if (rect.intersects(mOps[i].state->mBounds)) {
#if DEBUG_DEFER
- DEFER_LOGD("op intersects with op %p with bounds %f %f %f %f:", mOps[i],
- mOps[i]->state.mBounds.left, mOps[i]->state.mBounds.top,
- mOps[i]->state.mBounds.right, mOps[i]->state.mBounds.bottom);
- mOps[i]->output(2);
+ DEFER_LOGD("op intersects with op %p with bounds %f %f %f %f:", mOps[i].op,
+ mOps[i].state->mBounds.left, mOps[i].state->mBounds.top,
+ mOps[i].state->mBounds.right, mOps[i].state->mBounds.bottom);
+ mOps[i].op->output(2);
#endif
return true;
}
@@ -97,9 +97,9 @@ public:
status_t status = DrawGlInfo::kStatusDone;
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
for (unsigned int i = 0; i < mOps.size(); i++) {
- DrawOp* op = mOps[i];
-
- renderer.restoreDisplayState(op->state);
+ DrawOp* op = mOps[i].op;
+ const DeferredDisplayState* state = mOps[i].state;
+ renderer.restoreDisplayState(*state);
#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
renderer.eventMark(op->name());
@@ -108,7 +108,7 @@ public:
status |= op->applyDraw(renderer, dirty);
#if DEBUG_MERGE_BEHAVIOR
- Rect& bounds = mOps[i]->state.mBounds;
+ const Rect& bounds = state->mBounds;
int batchColor = 0x1f000000;
if (getBatchId() & 0x1) batchColor |= 0x0000ff;
if (getBatchId() & 0x2) batchColor |= 0x00ff00;
@@ -127,7 +127,7 @@ public:
Region uncovered(android::Rect(bounds.left, bounds.top, bounds.right, bounds.bottom));
for (unsigned int i = 0; i < mOps.size(); i++) {
- Rect &r = mOps[i]->state.mBounds;
+ const Rect &r = mOps[i].state->mBounds;
uncovered.subtractSelf(android::Rect(r.left, r.top, r.right, r.bottom));
}
return uncovered.isEmpty();
@@ -138,7 +138,7 @@ public:
inline int count() const { return mOps.size(); }
protected:
- Vector<DrawOp*> mOps;
+ Vector<OpStatePair> mOps;
Rect mBounds; // union of bounds of contained ops
private:
bool mAllOpsOpaque;
@@ -184,19 +184,19 @@ public:
* False positives can lead to information from the paints of subsequent merged operations being
* dropped, so we make simplifying qualifications on the ops that can merge, per op type.
*/
- bool canMergeWith(DrawOp* op) {
+ bool canMergeWith(const DrawOp* op, const DeferredDisplayState* state) {
bool isTextBatch = getBatchId() == DeferredDisplayList::kOpBatch_Text ||
getBatchId() == DeferredDisplayList::kOpBatch_ColorText;
// Overlapping other operations is only allowed for text without shadow. For other ops,
// multiDraw isn't guaranteed to overdraw correctly
- if (!isTextBatch || op->state.mDrawModifiers.mHasShadow) {
- if (intersects(op->state.mBounds)) return false;
+ if (!isTextBatch || state->mDrawModifiers.mHasShadow) {
+ if (intersects(state->mBounds)) return false;
}
- const DeferredDisplayState& lhs = op->state;
- const DeferredDisplayState& rhs = mOps[0]->state;
+ const DeferredDisplayState* lhs = state;
+ const DeferredDisplayState* rhs = mOps[0].state;
- if (NEQ_FALPHA(lhs.mAlpha, rhs.mAlpha)) return false;
+ if (NEQ_FALPHA(lhs->mAlpha, rhs->mAlpha)) return false;
/* Clipping compatibility check
*
@@ -204,9 +204,9 @@ public:
* clip for that side.
*/
const int currentFlags = mClipSideFlags;
- const int newFlags = op->state.mClipSideFlags;
+ const int newFlags = state->mClipSideFlags;
if (currentFlags != kClipSide_None || newFlags != kClipSide_None) {
- const Rect& opBounds = op->state.mBounds;
+ const Rect& opBounds = state->mBounds;
float boundsDelta = mBounds.left - opBounds.left;
if (!checkSide(currentFlags, newFlags, kClipSide_Left, boundsDelta)) return false;
boundsDelta = mBounds.top - opBounds.top;
@@ -220,9 +220,9 @@ public:
}
// if paints are equal, then modifiers + paint attribs don't need to be compared
- if (op->mPaint == mOps[0]->mPaint) return true;
+ if (op->mPaint == mOps[0].op->mPaint) return true;
- if (op->getPaintAlpha() != mOps[0]->getPaintAlpha()) return false;
+ if (op->getPaintAlpha() != mOps[0].op->getPaintAlpha()) return false;
/* Draw Modifiers compatibility check
*
@@ -236,8 +236,8 @@ public:
*
* These ignore cases prevent us from simply memcmp'ing the drawModifiers
*/
- const DrawModifiers& lhsMod = lhs.mDrawModifiers;
- const DrawModifiers& rhsMod = rhs.mDrawModifiers;
+ const DrawModifiers& lhsMod = lhs->mDrawModifiers;
+ const DrawModifiers& rhsMod = rhs->mDrawModifiers;
if (lhsMod.mShader != rhsMod.mShader) return false;
if (lhsMod.mColorFilter != rhsMod.mColorFilter) return false;
@@ -249,15 +249,15 @@ public:
return true;
}
- virtual void add(DrawOp* op, bool opaqueOverBounds) {
- DrawBatch::add(op, opaqueOverBounds);
+ virtual void add(DrawOp* op, DeferredDisplayState* state, bool opaqueOverBounds) {
+ DrawBatch::add(op, state, opaqueOverBounds);
- const int newClipSideFlags = op->state.mClipSideFlags;
+ const int newClipSideFlags = state->mClipSideFlags;
mClipSideFlags |= newClipSideFlags;
- if (newClipSideFlags & kClipSide_Left) mClipRect.left = op->state.mClip.left;
- if (newClipSideFlags & kClipSide_Top) mClipRect.top = op->state.mClip.top;
- if (newClipSideFlags & kClipSide_Right) mClipRect.right = op->state.mClip.right;
- if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = op->state.mClip.bottom;
+ if (newClipSideFlags & kClipSide_Left) mClipRect.left = state->mClip.left;
+ if (newClipSideFlags & kClipSide_Top) mClipRect.top = state->mClip.top;
+ if (newClipSideFlags & kClipSide_Right) mClipRect.right = state->mClip.right;
+ if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = state->mClip.bottom;
}
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
@@ -271,7 +271,7 @@ public:
// clipping in the merged case is done ahead of time since all ops share the clip (if any)
renderer.setupMergedMultiDraw(mClipSideFlags ? &mClipRect : NULL);
- DrawOp* op = mOps[0];
+ DrawOp* op = mOps[0].op;
DisplayListLogBuffer& buffer = DisplayListLogBuffer::getInstance();
buffer.writeCommand(0, "multiDraw");
buffer.writeCommand(1, op->name());
@@ -297,11 +297,11 @@ private:
class StateOpBatch : public Batch {
public:
// creates a single operation batch
- StateOpBatch(StateOp* op) : mOp(op) {}
+ StateOpBatch(const StateOp* op, const DeferredDisplayState* state) : mOp(op), mState(state) {}
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
DEFER_LOGD("replaying state op batch %p", this);
- renderer.restoreDisplayState(mOp->state);
+ renderer.restoreDisplayState(*mState);
// use invalid save count because it won't be used at flush time - RestoreToCountOp is the
// only one to use it, and we don't use that class at flush time, instead calling
@@ -313,16 +313,18 @@ public:
private:
const StateOp* mOp;
+ const DeferredDisplayState* mState;
};
class RestoreToCountBatch : public Batch {
public:
- RestoreToCountBatch(StateOp* op, int restoreCount) : mOp(op), mRestoreCount(restoreCount) {}
+ RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, int restoreCount) :
+ mOp(op), mState(state), mRestoreCount(restoreCount) {}
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount);
- renderer.restoreDisplayState(mOp->state);
+ renderer.restoreDisplayState(*mState);
renderer.restoreToCount(mRestoreCount);
return DrawGlInfo::kStatusDone;
}
@@ -330,6 +332,8 @@ public:
private:
// we use the state storage for the RestoreToCountOp, but don't replay the op itself
const StateOp* mOp;
+ const DeferredDisplayState* mState;
+
/*
* The count used here represents the flush() time saveCount. This is as opposed to the
* DisplayList record time, or defer() time values (which are RestoreToCountOp's mCount, and
@@ -480,12 +484,27 @@ void DeferredDisplayList::addRestoreToCount(OpenGLRenderer& renderer, StateOp* o
}
void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
- if (renderer.storeDisplayState(op->state, getDrawOpDeferFlags())) {
+ /* 1: op calculates local bounds */
+ DeferredDisplayState* const state = createState();
+ if (op->getLocalBounds(renderer.getDrawModifiers(), state->mBounds)) {
+ if (state->mBounds.isEmpty()) {
+ // valid empty bounds, don't bother deferring
+ tryRecycleState(state);
+ return;
+ }
+ } else {
+ state->mBounds.setEmpty();
+ }
+
+ /* 2: renderer calculates global bounds + stores state */
+ if (renderer.storeDisplayState(*state, getDrawOpDeferFlags())) {
+ tryRecycleState(state);
return; // quick rejected
}
+ /* 3: ask op for defer info, given renderer state */
DeferInfo deferInfo;
- op->onDefer(renderer, deferInfo);
+ op->onDefer(renderer, deferInfo, *state);
// complex clip has a complex set of expectations on the renderer state - for now, avoid taking
// the merge path in those cases
@@ -493,8 +512,8 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
deferInfo.opaqueOverBounds &= !recordingComplexClip() && mSaveStack.isEmpty();
if (CC_LIKELY(mAvoidOverdraw) && mBatches.size() &&
- op->state.mClipSideFlags != kClipSide_ConservativeFull &&
- deferInfo.opaqueOverBounds && op->state.mBounds.contains(mBounds)) {
+ state->mClipSideFlags != kClipSide_ConservativeFull &&
+ deferInfo.opaqueOverBounds && state->mBounds.contains(mBounds)) {
// avoid overdraw by resetting drawing state + discarding drawing ops
discardDrawingBatches(mBatches.size() - 1);
resetBatchingState();
@@ -503,7 +522,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
if (CC_UNLIKELY(renderer.getCaches().drawReorderDisabled)) {
// TODO: elegant way to reuse batches?
DrawBatch* b = new DrawBatch(deferInfo);
- b->add(op, deferInfo.opaqueOverBounds);
+ b->add(op, state, deferInfo.opaqueOverBounds);
mBatches.add(b);
return;
}
@@ -515,10 +534,10 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
// (eventually, should be similar shader)
int insertBatchIndex = mBatches.size();
if (!mBatches.isEmpty()) {
- if (op->state.mBounds.isEmpty()) {
+ if (state->mBounds.isEmpty()) {
// don't know the bounds for op, so add to last batch and start from scratch on next op
DrawBatch* b = new DrawBatch(deferInfo);
- b->add(op, deferInfo.opaqueOverBounds);
+ b->add(op, state, deferInfo.opaqueOverBounds);
mBatches.add(b);
resetBatchingState();
#if DEBUG_DEFER
@@ -531,7 +550,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
if (deferInfo.mergeable) {
// Try to merge with any existing batch with same mergeId.
if (mMergingBatches[deferInfo.batchId].get(deferInfo.mergeId, targetBatch)) {
- if (!((MergingDrawBatch*) targetBatch)->canMergeWith(op)) {
+ if (!((MergingDrawBatch*) targetBatch)->canMergeWith(op, state)) {
targetBatch = NULL;
}
}
@@ -554,14 +573,14 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
if (!targetBatch) break; // found insert position, quit
}
- if (overBatch->intersects(op->state.mBounds)) {
+ if (overBatch->intersects(state->mBounds)) {
// NOTE: it may be possible to optimize for special cases where two operations
// of the same batch/paint could swap order, such as with a non-mergeable
// (clipped) and a mergeable text operation
targetBatch = NULL;
#if DEBUG_DEFER
- DEFER_LOGD("op couldn't join batch %d, was intersected by batch %d",
- targetIndex, i);
+ DEFER_LOGD("op couldn't join batch %p, was intersected by batch %d",
+ targetBatch, i);
op->output(2);
#endif
break;
@@ -586,14 +605,15 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
mBatches.insertAt(targetBatch, insertBatchIndex);
}
- targetBatch->add(op, deferInfo.opaqueOverBounds);
+ targetBatch->add(op, state, deferInfo.opaqueOverBounds);
}
void DeferredDisplayList::storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* op) {
DEFER_LOGD("%p adding state op barrier at pos %d", this, mBatches.size());
- renderer.storeDisplayState(op->state, getStateOpDeferFlags());
- mBatches.add(new StateOpBatch(op));
+ DeferredDisplayState* state = createState();
+ renderer.storeDisplayState(*state, getStateOpDeferFlags());
+ mBatches.add(new StateOpBatch(op, state));
resetBatchingState();
}
@@ -604,8 +624,9 @@ void DeferredDisplayList::storeRestoreToCountBarrier(OpenGLRenderer& renderer, S
// store displayState for the restore operation, as it may be associated with a saveLayer that
// doesn't have kClip_SaveFlag set
- renderer.storeDisplayState(op->state, getStateOpDeferFlags());
- mBatches.add(new RestoreToCountBatch(op, newSaveCount));
+ DeferredDisplayState* state = createState();
+ renderer.storeDisplayState(*state, getStateOpDeferFlags());
+ mBatches.add(new RestoreToCountBatch(op, state, newSaveCount));
resetBatchingState();
}
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 1ef0152..3dcbd0b 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -18,11 +18,13 @@
#define ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H
#include <utils/Errors.h>
+#include <utils/LinearAllocator.h>
#include <utils/Vector.h>
+#include <utils/TinyHashMap.h>
#include "Matrix.h"
+#include "OpenGLRenderer.h"
#include "Rect.h"
-#include "utils/TinyHashMap.h"
class SkBitmap;
@@ -34,6 +36,8 @@ class DrawOp;
class SaveOp;
class SaveLayerOp;
class StateOp;
+
+class DeferredDisplayState;
class OpenGLRenderer;
class Batch;
@@ -42,6 +46,38 @@ class MergingDrawBatch;
typedef const void* mergeid_t;
+class DeferredDisplayState {
+public:
+ /** static void* operator new(size_t size); PURPOSELY OMITTED **/
+ static void* operator new(size_t size, LinearAllocator& allocator) {
+ return allocator.alloc(size);
+ }
+
+ // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped
+ Rect mBounds;
+
+ // the below are set and used by the OpenGLRenderer at record and deferred playback
+ bool mClipValid;
+ Rect mClip;
+ int mClipSideFlags; // specifies which sides of the bounds are clipped, unclipped if cleared
+ bool mClipped;
+ mat4 mMatrix;
+ DrawModifiers mDrawModifiers;
+ float mAlpha;
+};
+
+class OpStatePair {
+public:
+ OpStatePair()
+ : op(NULL), state(NULL) {}
+ OpStatePair(DrawOp* newOp, const DeferredDisplayState* newState)
+ : op(newOp), state(newState) {}
+ OpStatePair(const OpStatePair& other)
+ : op(other.op), state(other.state) {}
+ DrawOp* op;
+ const DeferredDisplayState* state;
+};
+
class DeferredDisplayList {
public:
DeferredDisplayList(const Rect& bounds, bool avoidOverdraw = true) :
@@ -84,6 +120,14 @@ public:
void addDrawOp(OpenGLRenderer& renderer, DrawOp* op);
private:
+ DeferredDisplayState* createState() {
+ return new (mAllocator) DeferredDisplayState();
+ }
+
+ void tryRecycleState(DeferredDisplayState* state) {
+ mAllocator.rewindIfLastAlloc(state, sizeof(DeferredDisplayState));
+ }
+
/**
* Resets the batching back-pointers, creating a barrier in the operation stream so that no ops
* added in the future will be inserted into a batch that already exist.
@@ -131,6 +175,8 @@ private:
* collide, which avoids the need to resolve mergeid collisions.
*/
TinyHashMap<mergeid_t, DrawBatch*> mMergingBatches[kOpBatch_Count];
+
+ LinearAllocator mAllocator;
};
/**
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 194be9e..1cd5f1c 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -26,6 +26,7 @@
#include <private/hwui/DrawGlInfo.h>
+#include <utils/LinearAllocator.h>
#include <utils/RefBase.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
@@ -35,8 +36,6 @@
#include <androidfw/ResourceTypes.h>
-#include "utils/LinearAllocator.h"
-
#include "Debug.h"
#define TRANSLATION 0x0001
@@ -114,7 +113,6 @@ public:
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
-
void defer(DeferStateStruct& deferStruct, const int level);
void replay(ReplayStateStruct& replayStruct, const int level);
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 42e11d0..a17942e 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -82,15 +82,6 @@ public:
// NOTE: it would be nice to declare constants and overriding the implementation in each op to
// point at the constants, but that seems to require a .cpp file
virtual const char* name() = 0;
-
- /**
- * Stores the relevant canvas state of the object between deferral and replay (if the canvas
- * state supports being stored) See OpenGLRenderer::simpleClipAndState()
- *
- * TODO: don't reserve space for StateOps that won't be deferred
- */
- DeferredDisplayState state;
-
};
class StateOp : public DisplayListOp {
@@ -129,14 +120,6 @@ public:
return;
}
- if (getLocalBounds(state.mBounds)) {
- // valid empty bounds, don't bother deferring
- if (state.mBounds.isEmpty()) return;
- } else {
- // empty bounds signify bounds can't be calculated
- state.mBounds.setEmpty();
- }
-
deferStruct.mDeferredList.addDrawOp(deferStruct.mRenderer, this);
}
@@ -159,11 +142,11 @@ public:
* reducing which operations are tagged as mergeable.
*/
virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
- const Vector<DrawOp*>& ops, const Rect& bounds) {
+ const Vector<OpStatePair>& ops, const Rect& bounds) {
status_t status = DrawGlInfo::kStatusDone;
for (unsigned int i = 0; i < ops.size(); i++) {
- renderer.restoreDisplayState(ops[i]->state, true);
- status |= ops[i]->applyDraw(renderer, dirty);
+ renderer.restoreDisplayState(*(ops[i].state), true);
+ status |= ops[i].op->applyDraw(renderer, dirty);
}
return status;
}
@@ -178,20 +161,23 @@ public:
*
* if a subclass can set deferInfo.mergeable to true, it should implement multiDraw()
*/
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {}
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {}
/**
* Query the conservative, local bounds (unmapped) bounds of the op.
*
* returns true if bounds exist
*/
- virtual bool getLocalBounds(Rect& localBounds) { return false; }
+ virtual bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
+ return false;
+ }
// TODO: better refine localbounds usage
void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; }
bool getQuickRejected() { return mQuickRejected; }
- inline int getPaintAlpha() {
+ inline int getPaintAlpha() const {
return OpenGLRenderer::getAlphaDirect(mPaint);
}
@@ -208,7 +194,7 @@ protected:
// Helper method for determining op opaqueness. Assumes op fills its bounds in local
// coordinates, and that paint's alpha is used
- inline bool isOpaqueOverBounds() {
+ inline bool isOpaqueOverBounds(const DeferredDisplayState& state) {
// ensure that local bounds cover mapped bounds
if (!state.mMatrix.isSimple()) return false;
@@ -251,12 +237,13 @@ public:
// default empty constructor for bounds, to be overridden in child constructor body
DrawBoundedOp(SkPaint* paint): DrawOp(paint) { }
- bool getLocalBounds(Rect& localBounds) {
+ bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
localBounds.set(mLocalBounds);
- if (state.mDrawModifiers.mHasShadow) {
+ if (drawModifiers.mHasShadow) {
+ // TODO: inspect paint's looper directly
Rect shadow(mLocalBounds);
- shadow.translate(state.mDrawModifiers.mShadowDx, state.mDrawModifiers.mShadowDy);
- shadow.outset(state.mDrawModifiers.mShadowRadius);
+ shadow.translate(drawModifiers.mShadowDx, drawModifiers.mShadowDy);
+ shadow.outset(drawModifiers.mShadowRadius);
localBounds.unionWith(shadow);
}
return true;
@@ -777,8 +764,10 @@ public:
* the current layer, if any.
*/
virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
- const Vector<DrawOp*>& ops, const Rect& bounds) {
- renderer.restoreDisplayState(state, true); // restore all but the clip
+ const Vector<OpStatePair>& ops, const Rect& bounds) {
+ const DeferredDisplayState& firstState = *(ops[0].state);
+ renderer.restoreDisplayState(firstState, true); // restore all but the clip
+
TextureVertex vertices[6 * ops.size()];
TextureVertex* vertex = &vertices[0];
@@ -788,14 +777,15 @@ public:
// TODO: manually handle rect clip for bitmaps by adjusting texCoords per op,
// and allowing them to be merged in getBatchId()
for (unsigned int i = 0; i < ops.size(); i++) {
- const Rect& opBounds = ops[i]->state.mBounds;
+ const DeferredDisplayState& state = *(ops[i].state);
+ const Rect& opBounds = state.mBounds;
// When we reach multiDraw(), the matrix can be either
// pureTranslate or simple (translate and/or scale).
// If the matrix is not pureTranslate, then we have a scale
- if (!ops[i]->state.mMatrix.isPureTranslate()) transformed = true;
+ if (state.mMatrix.isPureTranslate()) transformed = true;
Rect texCoords(0, 0, 1, 1);
- ((DrawBitmapOp*) ops[i])->mUvMapper.map(texCoords);
+ ((DrawBitmapOp*) ops[i].op)->mUvMapper.map(texCoords);
SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
@@ -806,8 +796,7 @@ public:
SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom);
if (hasLayer) {
- const Rect& dirty = ops[i]->state.mBounds;
- renderer.dirtyLayer(dirty.left, dirty.top, dirty.right, dirty.bottom);
+ renderer.dirtyLayer(opBounds.left, opBounds.top, opBounds.right, opBounds.bottom);
}
}
@@ -821,7 +810,8 @@ public:
virtual const char* name() { return "DrawBitmap"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
@@ -861,7 +851,8 @@ public:
virtual const char* name() { return "DrawBitmapMatrix"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
}
@@ -890,7 +881,8 @@ public:
virtual const char* name() { return "DrawBitmapRect"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
}
@@ -915,7 +907,8 @@ public:
virtual const char* name() { return "DrawBitmapData"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
}
};
@@ -939,7 +932,8 @@ public:
virtual const char* name() { return "DrawBitmapMesh"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
}
@@ -989,15 +983,16 @@ public:
* is also responsible for dirtying the current layer, if any.
*/
virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
- const Vector<DrawOp*>& ops, const Rect& bounds) {
- renderer.restoreDisplayState(state, true);
+ const Vector<OpStatePair>& ops, const Rect& bounds) {
+ const DeferredDisplayState& firstState = *(ops[0].state);
+ renderer.restoreDisplayState(firstState, true); // restore all but the clip
// Batches will usually contain a small number of items so it's
// worth performing a first iteration to count the exact number
// of vertices we need in the new mesh
uint32_t totalVertices = 0;
for (unsigned int i = 0; i < ops.size(); i++) {
- totalVertices += ((DrawPatchOp*) ops[i])->getMesh(renderer)->verticesCount;
+ totalVertices += ((DrawPatchOp*) ops[i].op)->getMesh(renderer)->verticesCount;
}
const bool hasLayer = renderer.hasLayer();
@@ -1012,7 +1007,8 @@ public:
// enforces ops drawn by this function to have a pure translate or
// identity matrix
for (unsigned int i = 0; i < ops.size(); i++) {
- DrawPatchOp* patchOp = (DrawPatchOp*) ops[i];
+ DrawPatchOp* patchOp = (DrawPatchOp*) ops[i].op;
+ const DeferredDisplayState* state = ops[i].state;
const Patch* opMesh = patchOp->getMesh(renderer);
uint32_t vertexCount = opMesh->verticesCount;
if (vertexCount == 0) continue;
@@ -1020,9 +1016,9 @@ public:
// We use the bounds to know where to translate our vertices
// Using patchOp->state.mBounds wouldn't work because these
// bounds are clipped
- const float tx = (int) floorf(patchOp->state.mMatrix.getTranslateX() +
+ const float tx = (int) floorf(state->mMatrix.getTranslateX() +
patchOp->mLocalBounds.left + 0.5f);
- const float ty = (int) floorf(patchOp->state.mMatrix.getTranslateY() +
+ const float ty = (int) floorf(state->mMatrix.getTranslateY() +
patchOp->mLocalBounds.top + 0.5f);
// Copy & transform all the vertices for the current operation
@@ -1074,12 +1070,13 @@ public:
virtual const char* name() { return "DrawPatch"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
- deferInfo.opaqueOverBounds = isOpaqueOverBounds() && mBitmap->isOpaque();
+ deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
}
private:
@@ -1119,7 +1116,7 @@ public:
DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
: DrawBoundedOp(left, top, right, bottom, paint) {};
- bool getLocalBounds(Rect& localBounds) {
+ bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
localBounds.set(mLocalBounds);
if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
localBounds.outset(strokeWidthOutset());
@@ -1127,7 +1124,8 @@ public:
return true;
}
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
if (mPaint->getPathEffect()) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
} else {
@@ -1152,9 +1150,10 @@ public:
OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds));
}
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
- DrawStrokableOp::onDefer(renderer, deferInfo);
- deferInfo.opaqueOverBounds = isOpaqueOverBounds() &&
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
+ DrawStrokableOp::onDefer(renderer, deferInfo, state);
+ deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) &&
mPaint->getStyle() == SkPaint::kFill_Style;
}
@@ -1177,7 +1176,8 @@ public:
virtual const char* name() { return "DrawRects"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = DeferredDisplayList::kOpBatch_Vertices;
}
@@ -1289,7 +1289,8 @@ public:
return renderer.drawPath(mPath, getPaint(renderer));
}
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
SkPaint* paint = getPaint(renderer);
renderer.getCaches().pathCache.precache(mPath, paint);
@@ -1324,7 +1325,8 @@ public:
virtual const char* name() { return "DrawLines"; }
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
deferInfo.batchId = mPaint->isAntiAlias() ?
DeferredDisplayList::kOpBatch_AlphaVertices :
DeferredDisplayList::kOpBatch_Vertices;
@@ -1360,7 +1362,8 @@ public:
OP_LOG("Draw some text, %d bytes", mBytesCount);
}
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
SkPaint* paint = getPaint(renderer);
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
fontRenderer.precache(paint, mText, mCount, mat4::identity());
@@ -1425,7 +1428,8 @@ public:
memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float));
}
- virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
+ virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+ const DeferredDisplayState& state) {
SkPaint* paint = getPaint(renderer);
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
const mat4& transform = renderer.findBestFontTransform(state.mMatrix);
@@ -1448,19 +1452,20 @@ public:
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
Rect bounds;
- getLocalBounds(bounds);
+ getLocalBounds(renderer.getDrawModifiers(), bounds);
return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
mPositions, getPaint(renderer), mTotalAdvance, bounds);
}
virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
- const Vector<DrawOp*>& ops, const Rect& bounds) {
+ const Vector<OpStatePair>& ops, const Rect& bounds) {
status_t status = DrawGlInfo::kStatusDone;
for (unsigned int i = 0; i < ops.size(); i++) {
+ const DeferredDisplayState& state = *(ops[i].state);
DrawOpMode drawOpMode = (i == ops.size() - 1) ? kDrawOpMode_Flush : kDrawOpMode_Defer;
- renderer.restoreDisplayState(ops[i]->state, true); // restore all but the clip
+ renderer.restoreDisplayState(state, true); // restore all but the clip
- DrawTextOp& op = *((DrawTextOp*)ops[i]);
+ DrawTextOp& op = *((DrawTextOp*)ops[i].op);
// quickReject() will not occure in drawText() so we can use mLocalBounds
// directly, we do not need to account for shadow by calling getLocalBounds()
status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 90dcf93..8866029 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -505,17 +505,12 @@ void DisplayListRenderer::addStateOp(StateOp* op) {
void DisplayListRenderer::addDrawOp(DrawOp* op) {
Rect localBounds;
- if (mDrawModifiers.mHasShadow) {
- op->state.mDrawModifiers = mDrawModifiers;
- }
- if (op->getLocalBounds(localBounds)) {
+ if (op->getLocalBounds(mDrawModifiers, localBounds)) {
bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
localBounds.right, localBounds.bottom);
op->setQuickRejected(rejected);
}
- if (mDrawModifiers.mHasShadow) {
- op->state.mDrawModifiers.reset();
- }
+
mHasDrawOps = true;
addOpInternal(op);
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 54f6d76..f74df97 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -98,24 +98,11 @@ enum ClipSideFlags {
kClipSide_ConservativeFull = 0x1F
};
-struct DeferredDisplayState {
- // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped
- Rect mBounds;
-
- // the below are set and used by the OpenGLRenderer at record and deferred playback
- bool mClipValid;
- Rect mClip;
- int mClipSideFlags; // specifies which sides of the bounds are clipped, unclipped if cleared
- bool mClipped;
- mat4 mMatrix;
- DrawModifiers mDrawModifiers;
- float mAlpha;
-};
-
///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
+class DeferredDisplayState;
class DisplayList;
class TextSetupFunctor;
class VertexBuffer;
@@ -423,7 +410,7 @@ public:
return getXfermode(paint->getXfermode());
}
- static inline int getAlphaDirect(SkPaint* paint) {
+ static inline int getAlphaDirect(const SkPaint* paint) {
if (!paint) return 255;
return paint->getAlpha();
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
index 7d6ca56..e47bf0c 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
@@ -57,7 +57,7 @@ import java.util.Map;
public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
private static final String LOG_TAG = "FusedPrintersProvider";
- private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = false;
private static final double WEIGHT_DECAY_COEFFICIENT = 0.95f;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index 1040edf..514e8ca 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -42,6 +42,7 @@ import android.print.IPrintDocumentAdapter;
import android.print.IWriteResultCallback;
import android.print.PageRange;
import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Resolution;
import android.print.PrintDocumentAdapter;
@@ -341,7 +342,11 @@ public class PrintJobConfigActivity extends Activity {
if (!mController.hasStarted()) {
mController.start();
}
- if (!printAttributesChanged() && mDocument.info != null) {
+ if (!printAttributesChanged()) {
+ if (mDocument.info == null) {
+ // We are waiting for the result of a layout, so do nothing.
+ return;
+ }
// If the attributes didn't change and we have done a layout, then
// we do not do a layout but may have to ask the app to write some
// pages. Hence, pretend layout completed and nothing changed, so
@@ -738,6 +743,8 @@ public class PrintJobConfigActivity extends Activity {
private PrinterInfo mCurrentPrinter;
+ private boolean mRequestedCurrentPrinterRefresh;
+
private final OnItemSelectedListener mOnItemSelectedListener =
new AdapterView.OnItemSelectedListener() {
@Override
@@ -757,34 +764,34 @@ public class PrintJobConfigActivity extends Activity {
return;
}
- mCurrPrintAttributes.clear();
+ mRequestedCurrentPrinterRefresh = false;
- PrinterInfo printer = (PrinterInfo) mDestinationSpinnerAdapter
+ mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter
.getItem(position);
PrintSpoolerService.peekInstance().setPrintJobPrinterNoPersistence(
- mPrintJobId, printer);
+ mPrintJobId, mCurrentPrinter);
- if (printer != null) {
- PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
- if (capabilities == null) {
- //TODO: We need a timeout for the update.
- mEditor.refreshCurrentPrinter();
- } else {
- capabilities.getDefaults(mCurrPrintAttributes);
- if (!mController.hasStarted()) {
- mController.start();
- }
- mController.update();
- }
+ if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
+ updateUi();
+ return;
}
- mCurrentPrinter = printer;
-
- updateUiForNewPrinterCapabilities();
+ PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
+ if (capabilities == null) {
+ // TODO: We need a timeout for the update.
+ mRequestedCurrentPrinterRefresh = true;
+ updateUi();
+ refreshCurrentPrinter();
+ } else {
+ updatePrintAttributes(capabilities);
+ updateUi();
+ mController.update();
+ }
} else if (spinner == mMediaSizeSpinner) {
- if (mIgnoreNextMediaSizeChange) {
- mIgnoreNextMediaSizeChange = false;
+ if (mOldMediaSizeSelectionIndex
+ == mMediaSizeSpinner.getSelectedItemPosition()) {
+ mOldMediaSizeSelectionIndex = AdapterView.INVALID_POSITION;
return;
}
SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(position);
@@ -793,8 +800,9 @@ public class PrintJobConfigActivity extends Activity {
mController.update();
}
} else if (spinner == mColorModeSpinner) {
- if (mIgnoreNextColorModeChange) {
- mIgnoreNextColorModeChange = false;
+ if (mOldColorModeSelectionIndex
+ == mColorModeSpinner.getSelectedItemPosition()) {
+ mOldColorModeSelectionIndex = AdapterView.INVALID_POSITION;
return;
}
SpinnerItem<Integer> colorModeItem =
@@ -810,16 +818,7 @@ public class PrintJobConfigActivity extends Activity {
}
SpinnerItem<Integer> orientationItem =
mOrientationSpinnerAdapter.getItem(position);
- MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
- if (orientationItem.value == ORIENTATION_PORTRAIT) {
- if (!mediaSize.isPortrait()) {
- mCurrPrintAttributes.setMediaSize(mediaSize.asPortrait());
- }
- } else {
- if (mediaSize.isPortrait()) {
- mCurrPrintAttributes.setMediaSize(mediaSize.asLandscape());
- }
- }
+ setCurrentPrintAttributesOrientation(orientationItem.value);
if (!hasErrors()) {
mController.update();
}
@@ -841,6 +840,105 @@ public class PrintJobConfigActivity extends Activity {
}
};
+ private void setCurrentPrintAttributesOrientation(int orientation) {
+ MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
+ if (orientation == ORIENTATION_PORTRAIT) {
+ if (!mediaSize.isPortrait()) {
+ // Rotate the media size.
+ mCurrPrintAttributes.setMediaSize(mediaSize.asPortrait());
+
+ // Rotate the resolution.
+ Resolution oldResolution = mCurrPrintAttributes.getResolution();
+ Resolution newResolution = new Resolution(
+ oldResolution.getId(),
+ oldResolution.getLabel(getPackageManager()),
+ oldResolution.getVerticalDpi(),
+ oldResolution.getHorizontalDpi());
+ mCurrPrintAttributes.setResolution(newResolution);
+
+ // Rotate the physical margins.
+ Margins oldMargins = mCurrPrintAttributes.getMargins();
+ Margins newMargins = new Margins(
+ oldMargins.getBottomMils(),
+ oldMargins.getLeftMils(),
+ oldMargins.getTopMils(),
+ oldMargins.getRightMils());
+ mCurrPrintAttributes.setMargins(newMargins);
+ }
+ } else {
+ if (mediaSize.isPortrait()) {
+ // Rotate the media size.
+ mCurrPrintAttributes.setMediaSize(mediaSize.asLandscape());
+
+ // Rotate the resolution.
+ Resolution oldResolution = mCurrPrintAttributes.getResolution();
+ Resolution newResolution = new Resolution(
+ oldResolution.getId(),
+ oldResolution.getLabel(getPackageManager()),
+ oldResolution.getVerticalDpi(),
+ oldResolution.getHorizontalDpi());
+ mCurrPrintAttributes.setResolution(newResolution);
+
+ // Rotate the physical margins.
+ Margins oldMargins = mCurrPrintAttributes.getMargins();
+ Margins newMargins = new Margins(
+ oldMargins.getTopMils(),
+ oldMargins.getRightMils(),
+ oldMargins.getBottomMils(),
+ oldMargins.getLeftMils());
+ mCurrPrintAttributes.setMargins(newMargins);
+ }
+ }
+ }
+
+ private void updatePrintAttributes(PrinterCapabilitiesInfo capabilities) {
+ PrintAttributes defaults = mTempPrintAttributes;
+ capabilities.getDefaults(defaults);
+
+ // Media size.
+ MediaSize currMediaSize = mCurrPrintAttributes.getMediaSize();
+ if (currMediaSize == null) {
+ mCurrPrintAttributes.setMediaSize(defaults.getMediaSize());
+ } else {
+ MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
+ List<MediaSize> mediaSizes = capabilities.getMediaSizes();
+ final int mediaSizeCount = mediaSizes.size();
+ for (int i = 0; i < mediaSizeCount; i++) {
+ MediaSize mediaSize = mediaSizes.get(i);
+ if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
+ mCurrPrintAttributes.setMediaSize(mediaSize);
+ break;
+ }
+ }
+ }
+
+ // Color mode.
+ final int colorMode = mCurrPrintAttributes.getColorMode();
+ if ((capabilities.getColorModes() & colorMode) == 0) {
+ mCurrPrintAttributes.setColorMode(colorMode);
+ }
+
+ // Resolution
+ Resolution resolution = mCurrPrintAttributes.getResolution();
+ if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
+ mCurrPrintAttributes.setResolution(defaults.getResolution());
+ }
+
+ // Margins.
+ Margins margins = mCurrPrintAttributes.getMargins();
+ if (margins == null) {
+ mCurrPrintAttributes.setMargins(defaults.getMargins());
+ } else {
+ Margins minMargins = capabilities.getMinMargins();
+ if (margins.getLeftMils() < minMargins.getLeftMils()
+ || margins.getTopMils() < minMargins.getTopMils()
+ || margins.getRightMils() > minMargins.getRightMils()
+ || margins.getBottomMils() > minMargins.getBottomMils()) {
+ mCurrPrintAttributes.setMargins(defaults.getMargins());
+ }
+ }
+ }
+
private final TextWatcher mCopiesTextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
@@ -952,8 +1050,8 @@ public class PrintJobConfigActivity extends Activity {
private int mEditorState;
private boolean mIgnoreNextDestinationChange;
- private boolean mIgnoreNextMediaSizeChange;
- private boolean mIgnoreNextColorModeChange;
+ private int mOldMediaSizeSelectionIndex;
+ private int mOldColorModeSelectionIndex;
private boolean mIgnoreNextOrientationChange;
private boolean mIgnoreNextRangeOptionChange;
private boolean mIgnoreNextCopiesChange;
@@ -993,11 +1091,22 @@ public class PrintJobConfigActivity extends Activity {
// capabilities, we refresh it.
if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
&& printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
- && printer.getCapabilities() == null) {
+ && printer.getCapabilities() == null
+ && !mRequestedCurrentPrinterRefresh) {
+ mRequestedCurrentPrinterRefresh = true;
refreshCurrentPrinter();
return;
}
+ // We just refreshed the current printer.
+ if (printer.getCapabilities() != null
+ && mRequestedCurrentPrinterRefresh) {
+ mRequestedCurrentPrinterRefresh = false;
+ updatePrintAttributes(printer.getCapabilities());
+ updateUi();
+ mController.update();
+ }
+
// Update the UI if capabilities changed.
boolean capabilitiesChanged = false;
@@ -1010,14 +1119,18 @@ public class PrintJobConfigActivity extends Activity {
capabilitiesChanged = true;
}
- if (capabilitiesChanged) {
- // Update the current printer.
+ // Update the UI if the status changed.
+ final boolean statusChanged = mCurrentPrinter.getStatus()
+ != printer.getStatus();
+
+ // Update the printer with the latest info.
+ if (!mCurrentPrinter.equals(printer)) {
mCurrentPrinter.copyFrom(printer);
+ }
- // If something changed during UI update...
+ if (capabilitiesChanged || statusChanged) {
+ // If something changed during update...
if (updateUi()) {
- // Update current attributes.
- printer.getCapabilities().getDefaults(mCurrPrintAttributes);
// Update the document.
mController.update();
}
@@ -1031,7 +1144,7 @@ public class PrintJobConfigActivity extends Activity {
@Override
public void onInvalidated() {
- updateUiForNewPrinterCapabilities();
+ /* do nothing - we always have one fake PDF printer */
}
});
@@ -1072,6 +1185,10 @@ public class PrintJobConfigActivity extends Activity {
showUi(UI_EDITING_PRINT_JOB, null);
bindUi();
+
+ mCurrentPrinter = mDestinationSpinnerAdapter.mFakePdfPrinter;
+ updatePrintAttributes(mCurrentPrinter.getCapabilities());
+
updateUi();
}
@@ -1393,7 +1510,7 @@ public class PrintJobConfigActivity extends Activity {
mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
mMediaSizeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
if (mMediaSizeSpinnerAdapter.getCount() > 0) {
- mIgnoreNextMediaSizeChange = true;
+ mOldMediaSizeSelectionIndex = 0;
}
// Color mode.
@@ -1401,7 +1518,7 @@ public class PrintJobConfigActivity extends Activity {
mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
mColorModeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
if (mColorModeSpinnerAdapter.getCount() > 0) {
- mIgnoreNextColorModeChange = true;
+ mOldColorModeSelectionIndex = 0;
}
// Orientation
@@ -1454,7 +1571,8 @@ public class PrintJobConfigActivity extends Activity {
Object item = mDestinationSpinnerAdapter.getItem(selectedIndex);
if (item instanceof PrinterInfo) {
PrinterInfo printer = (PrinterInfo) item;
- if (printer.getCapabilities() != null) {
+ if (printer.getCapabilities() != null
+ && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
allOptionsEnabled = true;
}
}
@@ -1470,14 +1588,14 @@ public class PrintJobConfigActivity extends Activity {
// Media size
if (mMediaSizeSpinner.getSelectedItemPosition() != AdapterView.INVALID_POSITION) {
- mIgnoreNextMediaSizeChange = true;
+ mOldMediaSizeSelectionIndex = AdapterView.INVALID_POSITION;
mMediaSizeSpinner.setSelection(AdapterView.INVALID_POSITION);
}
mMediaSizeSpinner.setEnabled(false);
// Color mode
if (mColorModeSpinner.getSelectedItemPosition() != AdapterView.INVALID_POSITION) {
- mIgnoreNextColorModeChange = true;
+ mOldColorModeSelectionIndex = AdapterView.INVALID_POSITION;
mColorModeSpinner.setSelection(AdapterView.INVALID_POSITION);
}
mColorModeSpinner.setEnabled(false);
@@ -1513,9 +1631,9 @@ public class PrintJobConfigActivity extends Activity {
} else {
boolean someAttributeSelectionChanged = false;
- PrintAttributes defaultAttributes = mTempPrintAttributes;
PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
+ PrintAttributes defaultAttributes = mTempPrintAttributes;
printer.getCapabilities().getDefaults(defaultAttributes);
// Media size.
@@ -1551,25 +1669,19 @@ public class PrintJobConfigActivity extends Activity {
mediaSize, mediaSize.getLabel(getPackageManager())));
}
- if (mediaSizeCount <= 0) {
- // No media sizes - clear the selection.
- mMediaSizeSpinner.setEnabled(false);
- // Clear selection and mark if selection changed.
- someAttributeSelectionChanged = setMediaSizeSpinnerSelectionNoCallback(
- AdapterView.INVALID_POSITION);
- } else {
- mMediaSizeSpinner.setEnabled(true);
+ mMediaSizeSpinner.setEnabled(true);
- if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
- // Select the old media size - nothing really changed.
- setMediaSizeSpinnerSelectionNoCallback(oldMediaSizeNewIndex);
- } else {
- // Select the first or the default and mark if selection changed.
- final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
- defaultAttributes.getMediaSize()), 0);
- someAttributeSelectionChanged = setMediaSizeSpinnerSelectionNoCallback(
- mediaSizeIndex);
- }
+ if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
+ // Select the old media size - nothing really changed.
+ setMediaSizeSpinnerSelectionNoCallback(oldMediaSizeNewIndex);
+ } else {
+ // Select the first or the default and mark if selection changed.
+ final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
+ defaultAttributes.getMediaSize()), 0);
+ setMediaSizeSpinnerSelectionNoCallback(mediaSizeIndex);
+ mCurrPrintAttributes.setMediaSize(mMediaSizeSpinnerAdapter
+ .getItem(mediaSizeIndex).value);
+ someAttributeSelectionChanged = true;
}
}
mMediaSizeSpinner.setEnabled(true);
@@ -1618,26 +1730,32 @@ public class PrintJobConfigActivity extends Activity {
mColorModeSpinnerAdapter.add(new SpinnerItem<Integer>(colorMode,
colorModeLabels[colorBitOffset]));
}
- final int colorModeCount = Integer.bitCount(colorModes);
- if (colorModeCount <= 0) {
- mColorModeSpinner.setEnabled(false);
- mColorModeSpinner.setSelection(AdapterView.INVALID_POSITION);
+ mColorModeSpinner.setEnabled(true);
+ if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
+ // Select the old color mode - nothing really changed.
+ setColorModeSpinnerSelectionNoCallback(oldColorModeNewIndex);
} else {
- mColorModeSpinner.setEnabled(true);
- if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
- // Select the old color mode - nothing really changed.
- setColorModeSpinnerSelectionNoCallback(oldColorModeNewIndex);
- } else {
- final int selectedColorModeIndex = Integer.numberOfTrailingZeros(
+ final int selectedColorModeIndex = Integer.numberOfTrailingZeros(
(colorModes & defaultAttributes.getColorMode()));
- someAttributeSelectionChanged = setColorModeSpinnerSelectionNoCallback(
- selectedColorModeIndex);
- }
+ setColorModeSpinnerSelectionNoCallback(selectedColorModeIndex);
+ mCurrPrintAttributes.setColorMode(mColorModeSpinnerAdapter
+ .getItem(selectedColorModeIndex).value);
+ someAttributeSelectionChanged = true;
}
}
mColorModeSpinner.setEnabled(true);
// Orientation
+ MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
+ if (mediaSize.isPortrait()
+ && mOrientationSpinner.getSelectedItemPosition() != 0) {
+ mIgnoreNextOrientationChange = true;
+ mOrientationSpinner.setSelection(0);
+ } else if (!mediaSize.isPortrait()
+ && mOrientationSpinner.getSelectedItemPosition() != 1) {
+ mIgnoreNextOrientationChange = true;
+ mOrientationSpinner.setSelection(1);
+ }
mOrientationSpinner.setEnabled(true);
// Range options
@@ -1723,50 +1841,18 @@ public class PrintJobConfigActivity extends Activity {
}
}
- private boolean setMediaSizeSpinnerSelectionNoCallback(int position) {
+ private void setMediaSizeSpinnerSelectionNoCallback(int position) {
if (mMediaSizeSpinner.getSelectedItemPosition() != position) {
- mIgnoreNextMediaSizeChange = true;
+ mOldMediaSizeSelectionIndex = position;
mMediaSizeSpinner.setSelection(position);
- return true;
}
- return false;
}
- private boolean setColorModeSpinnerSelectionNoCallback(int position) {
+ private void setColorModeSpinnerSelectionNoCallback(int position) {
if (mColorModeSpinner.getSelectedItemPosition() != position) {
- mIgnoreNextColorModeChange = true;
+ mOldColorModeSelectionIndex = position;
mColorModeSpinner.setSelection(position);
- return true;
- }
- return false;
- }
-
- private void updateUiForNewPrinterCapabilities() {
- // The printer changed so we want to start with a clean slate
- // for the print options and let them be populated from the
- // printer capabilities and use the printer defaults.
- if (!mMediaSizeSpinnerAdapter.isEmpty()) {
- mIgnoreNextMediaSizeChange = true;
- mMediaSizeSpinnerAdapter.clear();
- }
- if (!mColorModeSpinnerAdapter.isEmpty()) {
- mIgnoreNextColorModeChange = true;
- mColorModeSpinnerAdapter.clear();
- }
- if (mOrientationSpinner.getSelectedItemPosition() != 0) {
- mIgnoreNextOrientationChange = true;
- mOrientationSpinner.setSelection(0);
- }
- if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
- mIgnoreNextRangeOptionChange = true;
- mRangeOptionsSpinner.setSelection(0);
- }
- if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
- mIgnoreNextCopiesChange = true;
- mCopiesEditText.setText(MIN_COPIES_STRING);
}
-
- updateUi();
}
private void startSelectPrinterActivity() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
index 7266af8..76e548a 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
@@ -73,9 +73,9 @@ public final class PrintSpoolerService extends Service {
private static final String LOG_TAG = "PrintSpoolerService";
- private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = true;
+ private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = false;
- private static final boolean DEBUG_PERSISTENCE = true;
+ private static final boolean DEBUG_PERSISTENCE = false;
private static final boolean PERSISTNECE_MANAGER_ENABLED = true;
@@ -838,18 +838,8 @@ public final class PrintSpoolerService extends Service {
resolution.getHorizontalDpi()));
serializer.attribute(null, ATTR_VERTICAL_DPI, String.valueOf(
resolution.getVerticalDpi()));
- // We prefer to store only the package name and
- // resource id and fallback to the label.
- if (!TextUtils.isEmpty(mediaSize.mPackageName)
- && resolution.mLabelResId > 0) {
- serializer.attribute(null, ATTR_PACKAGE_NAME,
- resolution.mPackageName);
- serializer.attribute(null, ATTR_LABEL_RES_ID,
- String.valueOf(resolution.mLabelResId));
- } else {
- serializer.attribute(null, ATTR_LABEL,
- resolution.getLabel(getPackageManager()));
- }
+ serializer.attribute(null, ATTR_LABEL,
+ resolution.getLabel(getPackageManager()));
serializer.endTag(null, TAG_RESOLUTION);
}
@@ -1047,11 +1037,7 @@ public final class PrintSpoolerService extends Service {
ATTR_HORIZONTAL_DPI));
final int verticalDpi = Integer.parseInt(parser.getAttributeValue(null,
ATTR_VERTICAL_DPI));
- String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
- final int labelResId = Integer.parseInt(
- parser.getAttributeValue(null, ATTR_LABEL_RES_ID));
- Resolution resolution = new Resolution(id, label, packageName, labelResId,
- horizontalDpi, verticalDpi);
+ Resolution resolution = new Resolution(id, label, horizontalDpi, verticalDpi);
builder.setResolution(resolution);
parser.next();
skipEmptyTextTags(parser);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
index 4006a5a..fd14af9 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
@@ -17,7 +17,6 @@
package com.android.printspooler;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -43,7 +42,7 @@ import java.io.OutputStream;
final class RemotePrintDocumentAdapter {
private static final String LOG_TAG = "RemotePrintDocumentAdapter";
- private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = false;
private final IPrintDocumentAdapter mRemoteInterface;
diff --git a/services/java/com/android/server/location/FlpHardwareProvider.java b/services/java/com/android/server/location/FlpHardwareProvider.java
index 60893b8..fab84a8 100644
--- a/services/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/java/com/android/server/location/FlpHardwareProvider.java
@@ -26,6 +26,7 @@ import android.location.FusedBatchOptions;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
+import android.location.LocationRequest;
import android.content.Context;
import android.os.Bundle;
@@ -73,10 +74,19 @@ public class FlpHardwareProvider {
// register for listening for passive provider data
LocationManager manager = (LocationManager) mContext.getSystemService(
Context.LOCATION_SERVICE);
- manager.requestLocationUpdates(
+ final long minTime = 0;
+ final float minDistance = 0;
+ final boolean oneShot = false;
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
LocationManager.PASSIVE_PROVIDER,
- 0 /* minTime */,
- 0 /* minDistance */,
+ minTime,
+ minDistance,
+ oneShot);
+ // Don't keep track of this request since it's done on behalf of other clients
+ // (which are kept track of separately).
+ request.setHideFromAppOps(true);
+ manager.requestLocationUpdates(
+ request,
new NetworkLocationListener(),
Looper.myLooper());
}
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 6053c61..9c76c19 100644
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -512,8 +512,21 @@ public class GpsLocationProvider implements LocationProviderInterface {
public void run() {
LocationManager locManager =
(LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
- locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
- 0, 0, new NetworkLocationListener(), mHandler.getLooper());
+ final long minTime = 0;
+ final float minDistance = 0;
+ final boolean oneShot = false;
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ LocationManager.PASSIVE_PROVIDER,
+ minTime,
+ minDistance,
+ oneShot);
+ // Don't keep track of this request since it's done on behalf of other clients
+ // (which are kept track of separately).
+ request.setHideFromAppOps(true);
+ locManager.requestLocationUpdates(
+ request,
+ new NetworkLocationListener(),
+ mHandler.getLooper());
}
});
}
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index b5010f2..976a328 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -29,7 +29,6 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-import android.hardware.SystemSensorManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -119,7 +118,7 @@ final class DisplayPowerController {
// Proximity sensor debounce delay in milliseconds for positive or negative transitions.
private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
- private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 500;
+ private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
// Trigger proximity if distance is less than 5 cm.
private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
@@ -164,6 +163,10 @@ final class DisplayPowerController {
// Notifier for sending asynchronous notifications.
private final Notifier mNotifier;
+ // The display suspend blocker.
+ // Held while there are pending state change notifications.
+ private final SuspendBlocker mDisplaySuspendBlocker;
+
// The display blanker.
private final DisplayBlanker mDisplayBlanker;
@@ -271,7 +274,7 @@ final class DisplayPowerController {
// The raw non-debounced proximity sensor state.
private int mPendingProximity = PROXIMITY_UNKNOWN;
- private long mPendingProximityDebounceTime;
+ private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
// True if the screen was turned off because of the proximity sensor.
// When the screen turns on again, we report user activity to the power manager.
@@ -346,10 +349,11 @@ final class DisplayPowerController {
public DisplayPowerController(Looper looper, Context context, Notifier notifier,
LightsService lights, TwilightService twilight, SensorManager sensorManager,
DisplayManagerService displayManager,
- DisplayBlanker displayBlanker,
+ SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker,
Callbacks callbacks, Handler callbackHandler) {
mHandler = new DisplayControllerHandler(looper);
mNotifier = notifier;
+ mDisplaySuspendBlocker = displaySuspendBlocker;
mDisplayBlanker = displayBlanker;
mCallbacks = callbacks;
mCallbackHandler = callbackHandler;
@@ -601,7 +605,7 @@ final class DisplayPowerController {
if (!mScreenOffBecauseOfProximity
&& mProximity == PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = true;
- sendOnProximityPositive();
+ sendOnProximityPositiveWithWakelock();
setScreenOn(false);
}
} else if (mWaitingForNegativeProximity
@@ -616,7 +620,7 @@ final class DisplayPowerController {
if (mScreenOffBecauseOfProximity
&& mProximity != PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = false;
- sendOnProximityNegative();
+ sendOnProximityNegativeWithWakelock();
}
} else {
mWaitingForNegativeProximity = false;
@@ -737,7 +741,7 @@ final class DisplayPowerController {
}
}
}
- sendOnStateChanged();
+ sendOnStateChangedWithWakelock();
}
}
@@ -810,49 +814,67 @@ final class DisplayPowerController {
private void setProximitySensorEnabled(boolean enable) {
if (enable) {
if (!mProximitySensorEnabled) {
+ // Register the listener.
+ // Proximity sensor state already cleared initially.
mProximitySensorEnabled = true;
- mPendingProximity = PROXIMITY_UNKNOWN;
mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
}
} else {
if (mProximitySensorEnabled) {
+ // Unregister the listener.
+ // Clear the proximity sensor state for next time.
mProximitySensorEnabled = false;
mProximity = PROXIMITY_UNKNOWN;
+ mPendingProximity = PROXIMITY_UNKNOWN;
mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
mSensorManager.unregisterListener(mProximitySensorListener);
+ clearPendingProximityDebounceTime(); // release wake lock (must be last)
}
}
}
private void handleProximitySensorEvent(long time, boolean positive) {
- if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
- return; // no change
- }
- if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
- return; // no change
- }
+ if (mProximitySensorEnabled) {
+ if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
+ return; // no change
+ }
+ if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
+ return; // no change
+ }
- // Only accept a proximity sensor reading if it remains
- // stable for the entire debounce delay.
- mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
- if (positive) {
- mPendingProximity = PROXIMITY_POSITIVE;
- mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
- } else {
- mPendingProximity = PROXIMITY_NEGATIVE;
- mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
+ // Only accept a proximity sensor reading if it remains
+ // stable for the entire debounce delay. We hold a wake lock while
+ // debouncing the sensor.
+ mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
+ if (positive) {
+ mPendingProximity = PROXIMITY_POSITIVE;
+ setPendingProximityDebounceTime(
+ time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
+ } else {
+ mPendingProximity = PROXIMITY_NEGATIVE;
+ setPendingProximityDebounceTime(
+ time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
+ }
+
+ // Debounce the new sensor reading.
+ debounceProximitySensor();
}
- debounceProximitySensor();
}
private void debounceProximitySensor() {
- if (mPendingProximity != PROXIMITY_UNKNOWN) {
+ if (mProximitySensorEnabled
+ && mPendingProximity != PROXIMITY_UNKNOWN
+ && mPendingProximityDebounceTime >= 0) {
final long now = SystemClock.uptimeMillis();
if (mPendingProximityDebounceTime <= now) {
+ // Sensor reading accepted. Apply the change then release the wake lock.
mProximity = mPendingProximity;
- sendUpdatePowerState();
+ updatePowerState();
+ clearPendingProximityDebounceTime(); // release wake lock (must be last)
} else {
+ // Need to wait a little longer.
+ // Debounce again later. We continue holding a wake lock while waiting.
Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
@@ -860,6 +882,20 @@ final class DisplayPowerController {
}
}
+ private void clearPendingProximityDebounceTime() {
+ if (mPendingProximityDebounceTime >= 0) {
+ mPendingProximityDebounceTime = -1;
+ mDisplaySuspendBlocker.release(); // release wake lock
+ }
+ }
+
+ private void setPendingProximityDebounceTime(long debounceTime) {
+ if (mPendingProximityDebounceTime < 0) {
+ mDisplaySuspendBlocker.acquire(); // acquire wake lock
+ }
+ mPendingProximityDebounceTime = debounceTime;
+ }
+
private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
if (enable) {
if (!mLightSensorEnabled) {
@@ -1120,7 +1156,8 @@ final class DisplayPowerController {
return x + (y - x) * alpha;
}
- private void sendOnStateChanged() {
+ private void sendOnStateChangedWithWakelock() {
+ mDisplaySuspendBlocker.acquire();
mCallbackHandler.post(mOnStateChangedRunnable);
}
@@ -1128,10 +1165,12 @@ final class DisplayPowerController {
@Override
public void run() {
mCallbacks.onStateChanged();
+ mDisplaySuspendBlocker.release();
}
};
- private void sendOnProximityPositive() {
+ private void sendOnProximityPositiveWithWakelock() {
+ mDisplaySuspendBlocker.acquire();
mCallbackHandler.post(mOnProximityPositiveRunnable);
}
@@ -1139,10 +1178,12 @@ final class DisplayPowerController {
@Override
public void run() {
mCallbacks.onProximityPositive();
+ mDisplaySuspendBlocker.release();
}
};
- private void sendOnProximityNegative() {
+ private void sendOnProximityNegativeWithWakelock() {
+ mDisplaySuspendBlocker.acquire();
mCallbackHandler.post(mOnProximityNegativeRunnable);
}
@@ -1150,6 +1191,7 @@ final class DisplayPowerController {
@Override
public void run() {
mCallbacks.onProximityNegative();
+ mDisplaySuspendBlocker.release();
}
};
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 2167f67..fe09a33 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -63,7 +63,6 @@ import android.util.TimeUtils;
import android.view.WindowManagerPolicy;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -287,6 +286,9 @@ public final class PowerManagerService extends IPowerManager.Stub
// True if the device should wake up when plugged or unplugged.
private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
+ // True if the device should suspend when the screen is off due to proximity.
+ private boolean mSuspendWhenScreenOffDueToProximityConfig;
+
// True if dreams are supported on this device.
private boolean mDreamsSupportedConfig;
@@ -447,7 +449,7 @@ public final class PowerManagerService extends IPowerManager.Stub
// own handler thread to ensure timely operation.
mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
mContext, mNotifier, mLightsService, twilight, sensorManager,
- mDisplayManagerService, mDisplayBlanker,
+ mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker,
mDisplayPowerControllerCallbacks, mHandler);
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
@@ -514,6 +516,8 @@ public final class PowerManagerService extends IPowerManager.Stub
mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen);
+ mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
+ com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
mDreamsSupportedConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsSupported);
mDreamsEnabledByDefaultConfig = resources.getBoolean(
@@ -639,6 +643,7 @@ public final class PowerManagerService extends IPowerManager.Stub
}
}
+ @SuppressWarnings("deprecation")
private static boolean isScreenLock(final WakeLock wakeLock) {
switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
case PowerManager.FULL_WAKE_LOCK:
@@ -817,6 +822,7 @@ public final class PowerManagerService extends IPowerManager.Stub
}
}
+ @SuppressWarnings("deprecation")
private boolean isWakeLockLevelSupportedInternal(int level) {
synchronized (mLock) {
switch (level) {
@@ -1005,6 +1011,7 @@ public final class PowerManagerService extends IPowerManager.Stub
}
}
+ @SuppressWarnings("deprecation")
private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
if (DEBUG_SPEW) {
Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
@@ -1261,6 +1268,7 @@ public final class PowerManagerService extends IPowerManager.Stub
*
* This function must have no other side-effects.
*/
+ @SuppressWarnings("deprecation")
private void updateWakeLockSummaryLocked(int dirty) {
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
mWakeLockSummary = 0;
@@ -1299,7 +1307,7 @@ public final class PowerManagerService extends IPowerManager.Stub
break;
case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
if (mWakefulness != WAKEFULNESS_ASLEEP) {
- mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
+ mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
}
break;
}
@@ -1458,7 +1466,11 @@ public final class PowerManagerService extends IPowerManager.Stub
/**
* Returns true if the device is being kept awake by a wake lock, user activity
- * or the stay on while powered setting.
+ * or the stay on while powered setting. We also keep the phone awake when
+ * the proximity sensor returns a positive result so that the device does not
+ * lock while in a phone call. This function only controls whether the device
+ * will go to sleep or dream which is independent of whether it will be allowed
+ * to suspend.
*/
private boolean isBeingKeptAwakeLocked() {
return mStayOn
@@ -1749,10 +1761,8 @@ public final class PowerManagerService extends IPowerManager.Stub
* This function must have no other side-effects.
*/
private void updateSuspendBlockerLocked() {
- final boolean needWakeLockSuspendBlocker = (mWakeLockSummary != 0);
- final boolean needDisplaySuspendBlocker = (mUserActivitySummary != 0
- || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
- || !mDisplayReady || !mBootCompleted);
+ final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
+ final boolean needDisplaySuspendBlocker = needDisplaySuspendBlocker();
// First acquire suspend blockers if needed.
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
@@ -1775,6 +1785,27 @@ public final class PowerManagerService extends IPowerManager.Stub
}
}
+ /**
+ * Return true if we must keep a suspend blocker active on behalf of the display.
+ * We do so if the screen is on or is in transition between states.
+ */
+ private boolean needDisplaySuspendBlocker() {
+ if (!mDisplayReady) {
+ return true;
+ }
+ if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+ // If we asked for the screen to be on but it is off due to the proximity
+ // sensor then we may suspend but only if the configuration allows it.
+ // On some hardware it may not be safe to suspend because the proximity
+ // sensor may not be correctly configured as a wake-up source.
+ if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
+ || !mSuspendWhenScreenOffDueToProximityConfig) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override // Binder call
public boolean isScreenOn() {
final long ident = Binder.clearCallingIdentity();
@@ -2115,7 +2146,7 @@ public final class PowerManagerService extends IPowerManager.Stub
*
* @param brightness The overridden brightness.
*
- * @see Settings.System#SCREEN_BRIGHTNESS
+ * @see android.provider.Settings.System#SCREEN_BRIGHTNESS
*/
@Override // Binder call
public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
@@ -2255,7 +2286,16 @@ public final class PowerManagerService extends IPowerManager.Stub
pw.println();
pw.println("Settings and Configuration:");
+ pw.println(" mWakeUpWhenPluggedOrUnpluggedConfig="
+ + mWakeUpWhenPluggedOrUnpluggedConfig);
+ pw.println(" mSuspendWhenScreenOffDueToProximityConfig="
+ + mSuspendWhenScreenOffDueToProximityConfig);
pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);
+ pw.println(" mDreamsEnabledByDefaultConfig=" + mDreamsEnabledByDefaultConfig);
+ pw.println(" mDreamsActivatedOnSleepByDefaultConfig="
+ + mDreamsActivatedOnSleepByDefaultConfig);
+ pw.println(" mDreamsActivatedOnDockByDefaultConfig="
+ + mDreamsActivatedOnDockByDefaultConfig);
pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting);
pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/java/com/android/server/print/RemotePrintService.java
index ddff0ae..f15c760 100644
--- a/services/java/com/android/server/print/RemotePrintService.java
+++ b/services/java/com/android/server/print/RemotePrintService.java
@@ -21,11 +21,9 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
-import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
-import android.os.AsyncTask;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -39,8 +37,6 @@ import android.printservice.IPrintService;
import android.printservice.IPrintServiceClient;
import android.util.Slog;
-import com.android.internal.R;
-
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -55,7 +51,7 @@ final class RemotePrintService implements DeathRecipient {
private static final String LOG_TAG = "RemotePrintService";
- private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = false;
private final Context mContext;
@@ -65,7 +61,7 @@ final class RemotePrintService implements DeathRecipient {
private final RemotePrintSpooler mSpooler;
- private final UserState mUserState;
+ private final PrintServiceCallbacks mCallbacks;
private final int mUserId;
@@ -83,14 +79,24 @@ final class RemotePrintService implements DeathRecipient {
private boolean mDestroyed;
- private boolean mAllPrintJobsHandled;
+ private boolean mHasActivePrintJobs;
private boolean mHasPrinterDiscoverySession;
+ private List<PrinterId> mDiscoveryPriorityList;
+
+ private List<PrinterId> mTrackedPrinterList;
+
+ public static interface PrintServiceCallbacks {
+ public void onPrintersAdded(List<PrinterInfo> printers);
+ public void onPrintersRemoved(List<PrinterId> printerIds);
+ public void onServiceDied(RemotePrintService service);
+ }
+
public RemotePrintService(Context context, ComponentName componentName, int userId,
- RemotePrintSpooler spooler, UserState userState) {
+ RemotePrintSpooler spooler, PrintServiceCallbacks callbacks) {
mContext = context;
- mUserState = userState;
+ mCallbacks = callbacks;
mComponentName = componentName;
mIntent = new Intent().setComponent(mComponentName);
mUserId = userId;
@@ -99,15 +105,42 @@ final class RemotePrintService implements DeathRecipient {
mPrintServiceClient = new RemotePrintServiceClient(this);
}
+ public ComponentName getComponentName() {
+ return mComponentName;
+ }
+
public void destroy() {
mHandler.sendEmptyMessage(MyHandler.MSG_DESTROY);
}
private void handleDestroy() {
throwIfDestroyed();
+
+ // Stop tracking printers.
+ if (mTrackedPrinterList != null) {
+ final int trackedPrinterCount = mTrackedPrinterList.size();
+ for (int i = 0; i < trackedPrinterCount; i++) {
+ PrinterId printerId = mTrackedPrinterList.get(i);
+ if (printerId.getServiceName().equals(mComponentName)) {
+ handleStopPrinterStateTracking(printerId);
+ }
+ }
+ }
+
+ // Stop printer discovery.
+ if (mDiscoveryPriorityList != null) {
+ handleStopPrinterDiscovery();
+ }
+
+ // Destroy the discovery session.
+ if (mHasPrinterDiscoverySession) {
+ handleDestroyPrinterDiscoverySession();
+ }
+
+ // Unbind.
ensureUnbound();
- mAllPrintJobsHandled = false;
- mHasPrinterDiscoverySession = false;
+
+ // Done
mDestroyed = true;
}
@@ -121,21 +154,9 @@ final class RemotePrintService implements DeathRecipient {
}
private void handleBinderDied() {
- mAllPrintJobsHandled = false;
- mHasPrinterDiscoverySession = false;
- mPendingCommands.clear();
- ensureUnbound();
-
- // Makes sure all active print jobs are failed since the service
- // just died. Do this off the main thread since we do to allow
- // calls into the spooler on the main thread.
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- failAllActivePrintJobs();
- return null;
- }
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+ mPrintService.asBinder().unlinkToDeath(this, 0);
+ mPrintService = null;
+ mCallbacks.onServiceDied(this);
}
public void dump(PrintWriter pw, String prefix) {
@@ -148,32 +169,17 @@ final class RemotePrintService implements DeathRecipient {
pw.append(prefix).append(tab).append("bound=")
.append(String.valueOf(isBound())).println();
pw.append(prefix).append(tab).append("hasDicoverySession=")
- .append(String.valueOf(mHasPrinterDiscoverySession));
- }
-
- private void failAllActivePrintJobs() {
- List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(mComponentName,
- PrintJobInfo.STATE_ANY_ACTIVE, PrintManager.APP_ID_ANY);
- if (printJobs == null) {
- return;
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- final int printJobCount = printJobs.size();
- for (int i = 0; i < printJobCount; i++) {
- PrintJobInfo printJob = printJobs.get(i);
- mSpooler.setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
- mContext.getString(R.string.reason_unknown));
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ .append(String.valueOf(mHasPrinterDiscoverySession)).println();
+ pw.append(prefix).append(tab).append("isDiscoveringPrinters=")
+ .append(String.valueOf(mDiscoveryPriorityList != null)).println();
+ pw.append(prefix).append(tab).append("trackedPrinters=")
+ .append((mTrackedPrinterList != null) ? mTrackedPrinterList.toString() : "null");
}
private void handleOnAllPrintJobsHandled() {
throwIfDestroyed();
- mAllPrintJobsHandled = true;
+ mHasActivePrintJobs = false;
if (isBound()) {
if (DEBUG) {
@@ -217,7 +223,7 @@ final class RemotePrintService implements DeathRecipient {
private void handleOnPrintJobQueued(final PrintJobInfo printJob) {
throwIfDestroyed();
- mAllPrintJobsHandled = false;
+ mHasActivePrintJobs = true;
if (!isBound()) {
ensureBound();
@@ -296,7 +302,7 @@ final class RemotePrintService implements DeathRecipient {
// If the service has no print jobs and no active discovery
// session anymore we should disconnect from it.
- if (mAllPrintJobsHandled) {
+ if (!mHasActivePrintJobs) {
ensureUnbound();
}
}
@@ -326,6 +332,11 @@ final class RemotePrintService implements DeathRecipient {
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Error starting printer dicovery.", re);
}
+ // Take a note that we are doing discovery.
+ mDiscoveryPriorityList = new ArrayList<PrinterId>();
+ if (priorityList != null) {
+ mDiscoveryPriorityList.addAll(priorityList);
+ }
}
}
@@ -347,6 +358,8 @@ final class RemotePrintService implements DeathRecipient {
if (DEBUG) {
Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterDiscovery()");
}
+ // We are not doing discovery anymore.
+ mDiscoveryPriorityList = null;
try {
mPrintService.stopPrinterDiscovery();
} catch (RemoteException re) {
@@ -406,6 +419,11 @@ final class RemotePrintService implements DeathRecipient {
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Error requesting start printer tracking.", re);
}
+ // Take a note we are tracking the printer.
+ if (mTrackedPrinterList == null) {
+ mTrackedPrinterList = new ArrayList<PrinterId>();
+ }
+ mTrackedPrinterList.add(printerId);
}
}
@@ -428,6 +446,13 @@ final class RemotePrintService implements DeathRecipient {
if (DEBUG) {
Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterTracking()");
}
+ // We are no longer tracking the printer.
+ if (mTrackedPrinterList == null || !mTrackedPrinterList.remove(printerId)) {
+ return;
+ }
+ if (mTrackedPrinterList.isEmpty()) {
+ mTrackedPrinterList = null;
+ }
try {
mPrintService.stopPrinterStateTracking(printerId);
} catch (RemoteException re) {
@@ -461,6 +486,10 @@ final class RemotePrintService implements DeathRecipient {
}
mBinding = false;
mPendingCommands.clear();
+ mHasActivePrintJobs = false;
+ mHasPrinterDiscoverySession = false;
+ mDiscoveryPriorityList = null;
+ mTrackedPrinterList = null;
if (isBound()) {
try {
mPrintService.setClient(null);
@@ -500,11 +529,31 @@ final class RemotePrintService implements DeathRecipient {
handleBinderDied();
return;
}
+ // If there is a session, then the service died after creating
+ // a session. Hence, recreate the session.
+ if (mHasPrinterDiscoverySession) {
+ handleCreatePrinterDiscoverySession();
+ }
+ // If there is a priority list, then the service died during
+ // discovery and is restarted. Hence, start discovery.
+ if (mDiscoveryPriorityList != null) {
+ handleStartPrinterDiscovery(mDiscoveryPriorityList);
+ }
+ // If there is a tracked printer list, then the service died
+ // during discovery and is restarted. Hence, start tracking.
+ if (mTrackedPrinterList != null) {
+ final int trackedPrinterCount = mTrackedPrinterList.size();
+ for (int i = 0; i < trackedPrinterCount; i++) {
+ handleStartPrinterStateTracking(mTrackedPrinterList.get(i));
+ }
+ }
+ // Finally, do all the pending work.
final int pendingCommandCount = mPendingCommands.size();
for (int i = 0; i < pendingCommandCount; i++) {
Runnable pendingCommand = mPendingCommands.get(i);
pendingCommand.run();
}
+ mPendingCommands.clear();
}
@Override
@@ -677,7 +726,7 @@ final class RemotePrintService implements DeathRecipient {
throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
final long identity = Binder.clearCallingIdentity();
try {
- service.mUserState.onPrintersAdded(printers);
+ service.mCallbacks.onPrintersAdded(printers);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -691,7 +740,7 @@ final class RemotePrintService implements DeathRecipient {
throwIfPrinterIdsTampered(service.mComponentName, printerIds);
final long identity = Binder.clearCallingIdentity();
try {
- service.mUserState.onPrintersRemoved(printerIds);
+ service.mCallbacks.onPrintersRemoved(printerIds);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/java/com/android/server/print/RemotePrintSpooler.java b/services/java/com/android/server/print/RemotePrintSpooler.java
index 28a6186..45469ac 100644
--- a/services/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/java/com/android/server/print/RemotePrintSpooler.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
-import android.os.Build;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -57,7 +56,7 @@ final class RemotePrintSpooler {
private static final String LOG_TAG = "RemotePrintSpooler";
- private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = false;
private static final long BIND_SPOOLER_SERVICE_TIMEOUT = 10000;
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
index 5392975..70fe370 100644
--- a/services/java/com/android/server/print/UserState.java
+++ b/services/java/com/android/server/print/UserState.java
@@ -23,7 +23,8 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.Build;
+import android.os.AsyncTask;
+import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -32,6 +33,7 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.print.IPrinterDiscoveryObserver;
import android.print.PrintJobInfo;
+import android.print.PrintManager;
import android.print.PrinterId;
import android.print.PrinterInfo;
import android.printservice.PrintServiceInfo;
@@ -43,7 +45,9 @@ import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.R;
import com.android.internal.os.SomeArgs;
+import com.android.server.print.RemotePrintService.PrintServiceCallbacks;
import com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks;
import java.io.FileDescriptor;
@@ -58,11 +62,11 @@ import java.util.Set;
/**
* Represents the print state for a user.
*/
-final class UserState implements PrintSpoolerCallbacks {
+final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
private static final String LOG_TAG = "UserState";
- private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+ private static final boolean DEBUG = false;
private static final int MAX_ITEMS_PER_CALLBACK = 50;
@@ -246,6 +250,7 @@ final class UserState implements PrintSpoolerCallbacks {
}
}
+ @Override
public void onPrintersAdded(List<PrinterInfo> printers) {
synchronized (mLock) {
throwIfDestroyedLocked();
@@ -257,11 +262,11 @@ final class UserState implements PrintSpoolerCallbacks {
if (mPrinterDiscoverySession == null) {
return;
}
- // Request an updated.
mPrinterDiscoverySession.onPrintersAddedLocked(printers);
}
}
+ @Override
public void onPrintersRemoved(List<PrinterId> printerIds) {
synchronized (mLock) {
throwIfDestroyedLocked();
@@ -273,11 +278,28 @@ final class UserState implements PrintSpoolerCallbacks {
if (mPrinterDiscoverySession == null) {
return;
}
- // Request an updated.
mPrinterDiscoverySession.onPrintersRemovedLocked(printerIds);
}
}
+ @Override
+ public void onServiceDied(RemotePrintService service) {
+ synchronized (mLock) {
+ throwIfDestroyedLocked();
+ // No services - nothing to do.
+ if (mActiveServices.isEmpty()) {
+ return;
+ }
+ // Fail all print jobs.
+ failActivePrintJobsForService(service.getComponentName());
+ // No session - nothing to do.
+ if (mPrinterDiscoverySession == null) {
+ return;
+ }
+ mPrinterDiscoverySession.onServiceDiedLocked(service);
+ }
+ }
+
public void updateIfNeededLocked() {
throwIfDestroyedLocked();
if (readConfigurationLocked()) {
@@ -516,23 +538,72 @@ final class UserState implements PrintSpoolerCallbacks {
if (!mActiveServices.containsKey(serviceName)) {
RemotePrintService service = new RemotePrintService(
mContext, serviceName, mUserId, mSpooler, this);
- mActiveServices.put(serviceName, service);
- if (mPrinterDiscoverySession != null) {
- mPrinterDiscoverySession.onServiceAddedLocked(service);
- }
+ addServiceLocked(service);
}
} else {
RemotePrintService service = mActiveServices.remove(serviceName);
if (service != null) {
- service.destroy();
- if (mPrinterDiscoverySession != null) {
- mPrinterDiscoverySession.onServiceRemovedLocked(serviceName);
- }
+ removeServiceLocked(service);
}
}
}
}
+ private void addServiceLocked(RemotePrintService service) {
+ mActiveServices.put(service.getComponentName(), service);
+ if (mPrinterDiscoverySession != null) {
+ mPrinterDiscoverySession.onServiceAddedLocked(service);
+ }
+ }
+
+ private void removeServiceLocked(RemotePrintService service) {
+ // Fail all print jobs.
+ failActivePrintJobsForService(service.getComponentName());
+ // If discovery is in progress, tear down the service.
+ if (mPrinterDiscoverySession != null) {
+ mPrinterDiscoverySession.onServiceRemovedLocked(service);
+ } else {
+ // Otherwise, just destroy it.
+ service.destroy();
+ }
+ }
+
+ private void failActivePrintJobsForService(final ComponentName serviceName) {
+ // Makes sure all active print jobs are failed since the service
+ // just died. Do this off the main thread since we do to allow
+ // calls into the spooler on the main thread.
+ if (Looper.getMainLooper().isCurrentThread()) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ failActivePrintJobsForServiceInternal(serviceName);
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+ } else {
+ failActivePrintJobsForServiceInternal(serviceName);
+ }
+ }
+
+ private void failActivePrintJobsForServiceInternal(ComponentName serviceName) {
+ List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(serviceName,
+ PrintJobInfo.STATE_ANY_ACTIVE, PrintManager.APP_ID_ANY);
+ if (printJobs == null) {
+ return;
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final int printJobCount = printJobs.size();
+ for (int i = 0; i < printJobCount; i++) {
+ PrintJobInfo printJob = printJobs.get(i);
+ mSpooler.setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
+ mContext.getString(R.string.reason_unknown));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
private void throwIfDestroyedLocked() {
if (mDestroyed) {
throw new IllegalStateException("Cannot interact with a destroyed instance.");
@@ -603,17 +674,18 @@ final class UserState implements PrintSpoolerCallbacks {
return;
}
+ final boolean discoveryStarted = !mStartedPrinterDiscoveryTokens.isEmpty();
+
+ // Remember we got a start request to match with an end.
+ mStartedPrinterDiscoveryTokens.add(observer.asBinder());
+
// If printer discovery is ongoing and the start request has a list
// of printer to be checked, then we just request validating them.
- if (!mStartedPrinterDiscoveryTokens.isEmpty()
- && priorityList != null && !priorityList.isEmpty()) {
+ if (discoveryStarted && priorityList != null && !priorityList.isEmpty()) {
validatePrinters(priorityList);
return;
}
- // Remember we got a start request to match with an end.
- mStartedPrinterDiscoveryTokens.add(observer.asBinder());
-
// The service are already performing discovery - nothing to do.
if (mStartedPrinterDiscoveryTokens.size() > 1) {
return;
@@ -822,32 +894,20 @@ final class UserState implements PrintSpoolerCallbacks {
}
}
- public void onServiceRemovedLocked(ComponentName serviceName) {
+ public void onServiceRemovedLocked(RemotePrintService service) {
if (mIsDestroyed) {
Log.w(LOG_TAG, "Not updating removed service - session destroyed");
return;
}
- // No printers - nothing to do.
- if (mPrinters.isEmpty()) {
- return;
- }
- // Remove the printers for that service.
- List<PrinterId> removedPrinterIds = null;
- final int printerCount = mPrinters.size();
- for (int i = 0; i < printerCount; i++) {
- PrinterId printerId = mPrinters.keyAt(i);
- if (printerId.getServiceName().equals(serviceName)) {
- if (removedPrinterIds == null) {
- removedPrinterIds = new ArrayList<PrinterId>();
- }
- removedPrinterIds.add(printerId);
- }
- }
- if (!removedPrinterIds.isEmpty()) {
- mHandler.obtainMessage(
- SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED,
- removedPrinterIds).sendToTarget();
- }
+ // Remove the reported and tracked printers for that service.
+ ComponentName serviceName = service.getComponentName();
+ removePrintersForServiceLocked(serviceName);
+ service.destroy();
+ }
+
+ public void onServiceDiedLocked(RemotePrintService service) {
+ // Remove the reported by that service.
+ removePrintersForServiceLocked(service.getComponentName());
}
public void onServiceAddedLocked(RemotePrintService service) {
@@ -908,6 +968,34 @@ final class UserState implements PrintSpoolerCallbacks {
}
}
+ private void removePrintersForServiceLocked(ComponentName serviceName) {
+ // No printers - nothing to do.
+ if (mPrinters.isEmpty()) {
+ return;
+ }
+ // Remove the printers for that service.
+ List<PrinterId> removedPrinterIds = null;
+ final int printerCount = mPrinters.size();
+ for (int i = 0; i < printerCount; i++) {
+ PrinterId printerId = mPrinters.keyAt(i);
+ if (printerId.getServiceName().equals(serviceName)) {
+ if (removedPrinterIds == null) {
+ removedPrinterIds = new ArrayList<PrinterId>();
+ }
+ removedPrinterIds.add(printerId);
+ }
+ }
+ final int removedPrinterCount = removedPrinterIds.size();
+ for (int i = 0; i < removedPrinterCount; i++) {
+ mPrinters.remove(removedPrinterIds.get(i));
+ }
+ if (removedPrinterIds != null) {
+ mHandler.obtainMessage(
+ SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED,
+ removedPrinterIds).sendToTarget();
+ }
+ }
+
private void handleDispatchPrintersAdded(List<PrinterInfo> addedPrinters) {
final int observerCount = mDiscoveryObservers.beginBroadcast();
for (int i = 0; i < observerCount; i++) {
@@ -1026,14 +1114,17 @@ final class UserState implements PrintSpoolerCallbacks {
public static final int MSG_DISPATCH_PRINTERS_REMOVED = 4;
public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 5;
- public static final int MSG_START_PRINTER_DISCOVERY = 6;
- public static final int MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION = 7;
- public static final int MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION = 8;
- public static final int MSG_DISPATCH_START_PRINTER_DISCOVERY = 9;
- public static final int MSG_DISPATCH_STOP_PRINTER_DISCOVERY = 10;
- public static final int MSG_VALIDATE_PRINTERS = 11;
- public static final int MSG_START_PRINTER_STATE_TRACKING = 12;
- public static final int MSG_STOP_PRINTER_STATE_TRACKING = 13;
+ public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 6;
+ public static final int MSG_START_PRINTER_DISCOVERY = 7;
+ public static final int MSG_STOP_PRINTER_DISCOVERY = 8;
+ public static final int MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION = 9;
+ public static final int MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION = 10;
+ public static final int MSG_DISPATCH_START_PRINTER_DISCOVERY = 11;
+ public static final int MSG_DISPATCH_STOP_PRINTER_DISCOVERY = 12;
+ public static final int MSG_VALIDATE_PRINTERS = 13;
+ public static final int MSG_START_PRINTER_STATE_TRACKING = 14;
+ public static final int MSG_STOP_PRINTER_STATE_TRACKING = 15;
+ public static final int MSG_DESTROY_SERVICE = 16;
SessionHandler(Looper looper) {
super(looper, null, false);
@@ -1074,11 +1165,21 @@ final class UserState implements PrintSpoolerCallbacks {
service.createPrinterDiscoverySession();
} break;
+ case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: {
+ RemotePrintService service = (RemotePrintService) message.obj;
+ service.destroyPrinterDiscoverySession();
+ } break;
+
case MSG_START_PRINTER_DISCOVERY: {
RemotePrintService service = (RemotePrintService) message.obj;
service.startPrinterDiscovery(null);
} break;
+ case MSG_STOP_PRINTER_DISCOVERY: {
+ RemotePrintService service = (RemotePrintService) message.obj;
+ service.stopPrinterDiscovery();
+ } break;
+
case MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION: {
List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
handleDispatchCreatePrinterDiscoverySession(services);
@@ -1124,7 +1225,12 @@ final class UserState implements PrintSpoolerCallbacks {
PrinterId printerId = (PrinterId) args.arg2;
args.recycle();
handleStopPrinterStateTracking(service, printerId);
- }
+ } break;
+
+ case MSG_DESTROY_SERVICE: {
+ RemotePrintService service = (RemotePrintService) message.obj;
+ service.destroy();
+ } break;
}
}
}
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index ed2b8fd..46f100e 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -170,7 +170,20 @@ public final class WifiService extends IWifiManager.Stub {
}
/* Client commands are forwarded to state machine */
case WifiManager.CONNECT_NETWORK:
- case WifiManager.SAVE_NETWORK:
+ case WifiManager.SAVE_NETWORK: {
+ WifiConfiguration config = (WifiConfiguration) msg.obj;
+ if (config.isValid()) {
+ mWifiStateMachine.sendMessage(Message.obtain(msg));
+ } else {
+ Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
+ if (msg.what == WifiManager.CONNECT_NETWORK) {
+ replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
+ } else {
+ replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED);
+ }
+ }
+ break;
+ }
case WifiManager.FORGET_NETWORK:
case WifiManager.START_WPS:
case WifiManager.CANCEL_WPS:
@@ -185,6 +198,17 @@ public final class WifiService extends IWifiManager.Stub {
}
}
}
+
+ private void replyFailed(Message msg, int what) {
+ Message reply = msg.obtain();
+ reply.what = what;
+ reply.arg1 = WifiManager.INVALID_ARGS;
+ try {
+ msg.replyTo.send(reply);
+ } catch (RemoteException e) {
+ // There's not much we can do if reply can't be sent!
+ }
+ }
}
private ClientHandler mClientHandler;
@@ -555,7 +579,11 @@ public final class WifiService extends IWifiManager.Stub {
*/
public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
enforceChangePermission();
- mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
+ if (wifiConfig.isValid()) {
+ mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
+ } else {
+ Slog.e(TAG, "Invalid WifiConfiguration");
+ }
}
/**
@@ -588,7 +616,11 @@ public final class WifiService extends IWifiManager.Stub {
enforceChangePermission();
if (wifiConfig == null)
return;
- mWifiStateMachine.setWifiApConfiguration(wifiConfig);
+ if (wifiConfig.isValid()) {
+ mWifiStateMachine.setWifiApConfiguration(wifiConfig);
+ } else {
+ Slog.e(TAG, "Invalid WifiConfiguration");
+ }
}
/**
@@ -646,10 +678,15 @@ public final class WifiService extends IWifiManager.Stub {
*/
public int addOrUpdateNetwork(WifiConfiguration config) {
enforceChangePermission();
- if (mWifiStateMachineChannel != null) {
- return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
+ if (config.isValid()) {
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
+ } else {
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+ return -1;
+ }
} else {
- Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+ Slog.e(TAG, "bad network configuration");
return -1;
}
}
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index ea7904c..f79a4a6 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -115,6 +115,7 @@ class WifiConfigStore {
private Context mContext;
private static final String TAG = "WifiConfigStore";
private static final boolean DBG = true;
+ private static final boolean VDBG = false;
private static final String SUPPLICANT_CONFIG_FILE = "/data/misc/wifi/wpa_supplicant.conf";
@@ -154,7 +155,7 @@ class WifiConfigStore {
private static final String EOS = "eos";
private final LocalLog mLocalLog;
- WpaConfigFileObserver mFileObserver;
+ private final WpaConfigFileObserver mFileObserver;
private WifiNative mWifiNative;
private final KeyStore mKeyStore = KeyStore.getInstance();
@@ -163,10 +164,13 @@ class WifiConfigStore {
mContext = c;
mWifiNative = wn;
- if (DBG) {
+ if (VDBG) {
mLocalLog = mWifiNative.getLocalLog();
mFileObserver = new WpaConfigFileObserver();
mFileObserver.startWatching();
+ } else {
+ mLocalLog = null;
+ mFileObserver = null;
}
}
@@ -180,7 +184,7 @@ class WifiConfigStore {
public void onEvent(int event, String path) {
if (event == CLOSE_WRITE) {
File file = new File(SUPPLICANT_CONFIG_FILE);
- localLog("wpa_supplicant.conf changed; new size = " + file.length());
+ if (VDBG) localLog("wpa_supplicant.conf changed; new size = " + file.length());
}
}
}
@@ -245,7 +249,7 @@ class WifiConfigStore {
* @return false if the network id is invalid
*/
boolean selectNetwork(int netId) {
- localLog("selectNetwork", netId);
+ if (VDBG) localLog("selectNetwork", netId);
if (netId == INVALID_NETWORK_ID) return false;
// Reset the priority of each network at start or if it goes too high.
@@ -282,7 +286,7 @@ class WifiConfigStore {
* @return network update result
*/
NetworkUpdateResult saveNetwork(WifiConfiguration config) {
- localLog("saveNetwork", config.networkId);
+ if (VDBG) localLog("saveNetwork", config.networkId);
// A new network cannot have null SSID
if (config == null || (config.networkId == INVALID_NETWORK_ID &&
config.SSID == null)) {
@@ -331,7 +335,7 @@ class WifiConfigStore {
* @return {@code true} if it succeeds, {@code false} otherwise
*/
boolean forgetNetwork(int netId) {
- localLog("forgetNetwork", netId);
+ if (VDBG) localLog("forgetNetwork", netId);
if (mWifiNative.removeNetwork(netId)) {
mWifiNative.saveConfig();
removeConfigAndSendBroadcastIfNeeded(netId);
@@ -352,7 +356,7 @@ class WifiConfigStore {
* @return network Id
*/
int addOrUpdateNetwork(WifiConfiguration config) {
- localLog("addOrUpdateNetwork", config.networkId);
+ if (VDBG) localLog("addOrUpdateNetwork", config.networkId);
NetworkUpdateResult result = addOrUpdateNetworkNative(config);
if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
sendConfiguredNetworksChangedBroadcast(mConfiguredNetworks.get(result.getNetworkId()),
@@ -372,7 +376,7 @@ class WifiConfigStore {
* @return {@code true} if it succeeds, {@code false} otherwise
*/
boolean removeNetwork(int netId) {
- localLog("removeNetwork", netId);
+ if (VDBG) localLog("removeNetwork", netId);
boolean ret = mWifiNative.removeNetwork(netId);
if (ret) {
removeConfigAndSendBroadcastIfNeeded(netId);
@@ -407,10 +411,10 @@ class WifiConfigStore {
boolean enableNetwork(int netId, boolean disableOthers) {
boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
if (disableOthers) {
- localLog("enableNetwork(disableOthers=true) ", netId);
+ if (VDBG) localLog("enableNetwork(disableOthers=true) ", netId);
sendConfiguredNetworksChangedBroadcast();
} else {
- localLog("enableNetwork(disableOthers=false) ", netId);
+ if (VDBG) localLog("enableNetwork(disableOthers=false) ", netId);
WifiConfiguration enabledNetwork = null;
synchronized(mConfiguredNetworks) {
enabledNetwork = mConfiguredNetworks.get(netId);
@@ -437,7 +441,7 @@ class WifiConfigStore {
}
void disableAllNetworks() {
- localLog("disableAllNetworks");
+ if (VDBG) localLog("disableAllNetworks");
boolean networkDisabled = false;
for(WifiConfiguration config : mConfiguredNetworks.values()) {
if(config != null && config.status != Status.DISABLED) {
@@ -470,7 +474,7 @@ class WifiConfigStore {
* @return {@code true} if it succeeds, {@code false} otherwise
*/
boolean disableNetwork(int netId, int reason) {
- localLog("disableNetwork", netId);
+ if (VDBG) localLog("disableNetwork", netId);
boolean ret = mWifiNative.disableNetwork(netId);
WifiConfiguration network = null;
WifiConfiguration config = mConfiguredNetworks.get(netId);
@@ -683,33 +687,33 @@ class WifiConfigStore {
if (mNetworkIds.containsKey(configKey(config))) {
// That SSID is already known, just ignore this duplicate entry
- localLog("discarded duplicate network", config.networkId);
+ if (VDBG) localLog("discarded duplicate network", config.networkId);
} else {
mConfiguredNetworks.put(config.networkId, config);
mNetworkIds.put(configKey(config), config.networkId);
- localLog("loaded configured network", config.networkId);
+ if (VDBG) localLog("loaded configured network", config.networkId);
}
}
readIpAndProxyConfigurations();
sendConfiguredNetworksChangedBroadcast();
- localLog("loadConfiguredNetworks loaded " + mNetworkIds.size() + " networks");
+ if (VDBG) localLog("loadConfiguredNetworks loaded " + mNetworkIds.size() + " networks");
if (mNetworkIds.size() == 0) {
// no networks? Lets log if the wpa_supplicant.conf file contents
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(SUPPLICANT_CONFIG_FILE));
- localLog("--- Begin wpa_supplicant.conf Contents ---");
+ if (VDBG) localLog("--- Begin wpa_supplicant.conf Contents ---");
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- localLog(line);
+ if (VDBG) localLog(line);
}
- localLog("--- End wpa_supplicant.conf Contents ---");
+ if (VDBG) localLog("--- End wpa_supplicant.conf Contents ---");
} catch (FileNotFoundException e) {
- localLog("Could not open " + SUPPLICANT_CONFIG_FILE + ", " + e);
+ if (VDBG) localLog("Could not open " + SUPPLICANT_CONFIG_FILE + ", " + e);
} catch (IOException e) {
- localLog("Could not read " + SUPPLICANT_CONFIG_FILE + ", " + e);
+ if (VDBG) localLog("Could not read " + SUPPLICANT_CONFIG_FILE + ", " + e);
} finally {
try {
if (reader != null) {
@@ -1050,7 +1054,7 @@ class WifiConfigStore {
* refer to an existing configuration.
*/
- localLog("addOrUpdateNetworkNative " + config.getPrintableSsid());
+ if (VDBG) localLog("addOrUpdateNetworkNative " + config.getPrintableSsid());
int netId = config.networkId;
boolean newNetwork = false;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index de377ee..2ce584b 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -348,6 +348,20 @@ public class WifiConfiguration implements Parcelable {
linkProperties = new LinkProperties();
}
+ /**
+ * indicates whether the configuration is valid
+ * @return true if valid, false otherwise
+ * @hide
+ */
+ public boolean isValid() {
+ if (allowedKeyManagement.cardinality() > 1) {
+ return false;
+ }
+
+ // TODO: Add more checks
+ return true;
+ }
+
@Override
public String toString() {
StringBuilder sbuf = new StringBuilder();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index c3bf9c1..3223cb3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1370,6 +1370,13 @@ public class WifiManager {
/** WPS timed out {@hide} */
public static final int WPS_TIMED_OUT = 7;
+ /**
+ * Passed with {@link ActionListener#onFailure}.
+ * Indicates that the operation failed due to invalid inputs
+ * @hide
+ */
+ public static final int INVALID_ARGS = 8;
+
/** Interface for callback invocation on an application action {@hide} */
public interface ActionListener {
/** The operation succeeded */
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 3deac1b..520668e 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -39,6 +39,7 @@ import java.util.Locale;
public class WifiNative {
private static final boolean DBG = false;
+ private static final boolean VDBG = false;
private final String mTAG;
private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
@@ -117,12 +118,12 @@ public class WifiNative {
public boolean connectToSupplicant() {
// No synchronization necessary .. it is implemented in WifiMonitor
- localLog(mInterfacePrefix + "connectToSupplicant");
+ if (VDBG) localLog(mInterfacePrefix + "connectToSupplicant");
return connectToSupplicantNative();
}
public void closeSupplicantConnection() {
- localLog(mInterfacePrefix + "closeSupplicantConnection");
+ if (VDBG) localLog(mInterfacePrefix + "closeSupplicantConnection");
closeSupplicantConnectionNative();
}
@@ -135,9 +136,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doBoolean: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
- localLog(cmdId + "->" + mInterfacePrefix + command);
+ if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
boolean result = doBooleanCommandNative(mInterfacePrefix + command);
- localLog(cmdId + "<-" + result);
+ if (VDBG) localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result);
return result;
}
@@ -147,9 +148,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doInt: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
- localLog(cmdId + "->" + mInterfacePrefix + command);
+ if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
int result = doIntCommandNative(mInterfacePrefix + command);
- localLog(cmdId + "<-" + result);
+ if (VDBG) localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result);
return result;
}
@@ -159,9 +160,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doString: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
- localLog(cmdId + "->" + mInterfacePrefix + command);
+ if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
String result = doStringCommandNative(mInterfacePrefix + command);
- localLog(cmdId + "<-" + result);
+ if (VDBG) localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result);
return result;
}