Merge "Sometimes write may be called twice in a row for the same content."
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index e53ce8b..bb09c90 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -18,6 +18,8 @@
import android.graphics.Matrix;
+import java.util.ArrayList;
+
/**
* <p>A display list records a series of graphics related operations and can replay
* them later. Display lists are usually built by recording operations on a
@@ -120,12 +122,23 @@
*
* @hide
*/
-public abstract class DisplayList {
+public class DisplayList {
private boolean mDirty;
+ private ArrayList<DisplayList> mChildDisplayLists;
+
+ private GLES20RecordingCanvas mCanvas;
+ private boolean mValid;
+
+ // Used for debugging
+ private final String mName;
+
+ // The native display list will be destroyed when this object dies.
+ // DO NOT overwrite this reference once it is set.
+ private DisplayListFinalizer mFinalizer;
/**
* Flag used when calling
- * {@link HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)}
+ * {@link HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)}
* When this flag is set, draw operations lying outside of the bounds of the
* display list will be culled early. It is recommeneded to always set this
* flag.
@@ -173,6 +186,10 @@
*/
public static final int STATUS_DREW = 0x4;
+ private DisplayList(String name) {
+ mName = name;
+ }
+
/**
* Creates a new display list that can be used to record batches of
* drawing operations.
@@ -184,7 +201,7 @@
* @hide
*/
public static DisplayList create(String name) {
- return new GLES20DisplayList(name);
+ return new DisplayList(name);
}
/**
@@ -202,7 +219,21 @@
* @see #end()
* @see #isValid()
*/
- public abstract HardwareCanvas start(int width, int height);
+ public HardwareCanvas start(int width, int height) {
+ if (mCanvas != null) {
+ throw new IllegalStateException("Recording has already started");
+ }
+
+ mValid = false;
+ mCanvas = GLES20RecordingCanvas.obtain(this);
+ mCanvas.start();
+
+ mCanvas.setViewport(width, height);
+ // The dirty rect should always be null for a display list
+ mCanvas.onPreDraw(null);
+
+ return mCanvas;
+ }
/**
* Ends the recording for this display list. A display list cannot be
@@ -212,7 +243,20 @@
* @see #start(int, int)
* @see #isValid()
*/
- public abstract void end();
+ public void end() {
+ if (mCanvas != null) {
+ mCanvas.onPostDraw();
+ if (mFinalizer != null) {
+ mCanvas.end(mFinalizer.mNativeDisplayList);
+ } else {
+ mFinalizer = new DisplayListFinalizer(mCanvas.end(0));
+ nSetDisplayListName(mFinalizer.mNativeDisplayList, mName);
+ }
+ mCanvas.recycle();
+ mCanvas = null;
+ mValid = true;
+ }
+ }
/**
* Clears resources held onto by this display list. After calling this method
@@ -221,8 +265,26 @@
* @see #isValid()
* @see #reset()
*/
- public abstract void clear();
+ public void clear() {
+ clearDirty();
+ if (mCanvas != null) {
+ mCanvas.recycle();
+ mCanvas = null;
+ }
+ mValid = false;
+
+ clearReferences();
+ }
+
+ void clearReferences() {
+ if (mChildDisplayLists != null) mChildDisplayLists.clear();
+ }
+
+ ArrayList<DisplayList> getChildDisplayLists() {
+ if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>();
+ return mChildDisplayLists;
+ }
/**
* Reset native resources. This is called when cleaning up the state of display lists
@@ -233,7 +295,12 @@
*
* @hide
*/
- public abstract void reset();
+ public void reset() {
+ if (hasNativeDisplayList()) {
+ nReset(mFinalizer.mNativeDisplayList);
+ }
+ clear();
+ }
/**
* Sets the dirty flag. When a display list is dirty, {@link #clear()} should
@@ -279,16 +346,30 @@
*
* @return boolean true if the display list is able to be replayed, false otherwise.
*/
- public abstract boolean isValid();
+ public boolean isValid() { return mValid; }
/**
* Return the amount of memory used by this display list.
- *
+ *
* @return The size of this display list in bytes
*
* @hide
*/
- public abstract int getSize();
+ public int getSize() {
+ if (mFinalizer == null) return 0;
+ return nGetDisplayListSize(mFinalizer.mNativeDisplayList);
+ }
+
+ boolean hasNativeDisplayList() {
+ return mValid && mFinalizer != null;
+ }
+
+ int getNativeDisplayList() {
+ if (!mValid || mFinalizer == null) {
+ throw new IllegalStateException("The display list is not valid.");
+ }
+ return mFinalizer.mNativeDisplayList;
+ }
///////////////////////////////////////////////////////////////////////////
// DisplayList Property Setters
@@ -303,7 +384,11 @@
*
* @hide
*/
- public abstract void setCaching(boolean caching);
+ public void setCaching(boolean caching) {
+ if (hasNativeDisplayList()) {
+ nSetCaching(mFinalizer.mNativeDisplayList, caching);
+ }
+ }
/**
* Set whether the display list should clip itself to its bounds. This property is controlled by
@@ -311,7 +396,11 @@
*
* @param clipToBounds true if the display list should clip to its bounds
*/
- public abstract void setClipToBounds(boolean clipToBounds);
+ public void setClipToBounds(boolean clipToBounds) {
+ if (hasNativeDisplayList()) {
+ nSetClipToBounds(mFinalizer.mNativeDisplayList, clipToBounds);
+ }
+ }
/**
* Set the static matrix on the display list. The specified matrix is combined with other
@@ -322,7 +411,11 @@
* @see #getMatrix(android.graphics.Matrix)
* @see #getMatrix()
*/
- public abstract void setMatrix(Matrix matrix);
+ public void setMatrix(Matrix matrix) {
+ if (hasNativeDisplayList()) {
+ nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
+ }
+ }
/**
* Returns the static matrix set on this display list.
@@ -348,7 +441,12 @@
* @see #getMatrix()
* @see #setMatrix(android.graphics.Matrix)
*/
- public abstract Matrix getMatrix(Matrix matrix);
+ public Matrix getMatrix(Matrix matrix) {
+ if (hasNativeDisplayList()) {
+ nGetMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
+ }
+ return matrix;
+ }
/**
* Set the Animation matrix on the display list. This matrix exists if an Animation is
@@ -360,7 +458,12 @@
*
* @hide
*/
- public abstract void setAnimationMatrix(Matrix matrix);
+ public void setAnimationMatrix(Matrix matrix) {
+ if (hasNativeDisplayList()) {
+ nSetAnimationMatrix(mFinalizer.mNativeDisplayList,
+ (matrix != null) ? matrix.native_instance : 0);
+ }
+ }
/**
* Sets the translucency level for the display list.
@@ -370,7 +473,11 @@
* @see View#setAlpha(float)
* @see #getAlpha()
*/
- public abstract void setAlpha(float alpha);
+ public void setAlpha(float alpha) {
+ if (hasNativeDisplayList()) {
+ nSetAlpha(mFinalizer.mNativeDisplayList, alpha);
+ }
+ }
/**
* Returns the translucency level of this display list.
@@ -379,7 +486,12 @@
*
* @see #setAlpha(float)
*/
- public abstract float getAlpha();
+ public float getAlpha() {
+ if (hasNativeDisplayList()) {
+ return nGetAlpha(mFinalizer.mNativeDisplayList);
+ }
+ return 1.0f;
+ }
/**
* Sets whether the display list renders content which overlaps. Non-overlapping rendering
@@ -392,7 +504,11 @@
* @see android.view.View#hasOverlappingRendering()
* @see #hasOverlappingRendering()
*/
- public abstract void setHasOverlappingRendering(boolean hasOverlappingRendering);
+ public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
+ if (hasNativeDisplayList()) {
+ nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering);
+ }
+ }
/**
* Indicates whether the content of this display list overlaps.
@@ -401,7 +517,13 @@
*
* @see #setHasOverlappingRendering(boolean)
*/
- public abstract boolean hasOverlappingRendering();
+ public boolean hasOverlappingRendering() {
+ //noinspection SimplifiableIfStatement
+ if (hasNativeDisplayList()) {
+ return nHasOverlappingRendering(mFinalizer.mNativeDisplayList);
+ }
+ return true;
+ }
/**
* Sets the translation value for the display list on the X axis
@@ -411,14 +533,23 @@
* @see View#setTranslationX(float)
* @see #getTranslationX()
*/
- public abstract void setTranslationX(float translationX);
+ public void setTranslationX(float translationX) {
+ if (hasNativeDisplayList()) {
+ nSetTranslationX(mFinalizer.mNativeDisplayList, translationX);
+ }
+ }
/**
* Returns the translation value for this display list on the X axis, in pixels.
*
* @see #setTranslationX(float)
*/
- public abstract float getTranslationX();
+ public float getTranslationX() {
+ if (hasNativeDisplayList()) {
+ return nGetTranslationX(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the translation value for the display list on the Y axis
@@ -428,14 +559,23 @@
* @see View#setTranslationY(float)
* @see #getTranslationY()
*/
- public abstract void setTranslationY(float translationY);
+ public void setTranslationY(float translationY) {
+ if (hasNativeDisplayList()) {
+ nSetTranslationY(mFinalizer.mNativeDisplayList, translationY);
+ }
+ }
/**
* Returns the translation value for this display list on the Y axis, in pixels.
*
* @see #setTranslationY(float)
*/
- public abstract float getTranslationY();
+ public float getTranslationY() {
+ if (hasNativeDisplayList()) {
+ return nGetTranslationY(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the translation value for the display list on the Z axis
@@ -443,14 +583,23 @@
* @see View#setTranslationZ(float)
* @see #getTranslationZ()
*/
- public abstract void setTranslationZ(float translationZ);
+ public void setTranslationZ(float translationZ) {
+ if (hasNativeDisplayList()) {
+ nSetTranslationZ(mFinalizer.mNativeDisplayList, translationZ);
+ }
+ }
/**
* Returns the translation value for this display list on the Z axis.
*
* @see #setTranslationZ(float)
*/
- public abstract float getTranslationZ();
+ public float getTranslationZ() {
+ if (hasNativeDisplayList()) {
+ return nGetTranslationZ(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the rotation value for the display list around the Z axis
@@ -460,14 +609,23 @@
* @see View#setRotation(float)
* @see #getRotation()
*/
- public abstract void setRotation(float rotation);
+ public void setRotation(float rotation) {
+ if (hasNativeDisplayList()) {
+ nSetRotation(mFinalizer.mNativeDisplayList, rotation);
+ }
+ }
/**
* Returns the rotation value for this display list around the Z axis, in degrees.
*
* @see #setRotation(float)
*/
- public abstract float getRotation();
+ public float getRotation() {
+ if (hasNativeDisplayList()) {
+ return nGetRotation(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the rotation value for the display list around the X axis
@@ -477,14 +635,23 @@
* @see View#setRotationX(float)
* @see #getRotationX()
*/
- public abstract void setRotationX(float rotationX);
+ public void setRotationX(float rotationX) {
+ if (hasNativeDisplayList()) {
+ nSetRotationX(mFinalizer.mNativeDisplayList, rotationX);
+ }
+ }
/**
* Returns the rotation value for this display list around the X axis, in degrees.
*
* @see #setRotationX(float)
*/
- public abstract float getRotationX();
+ public float getRotationX() {
+ if (hasNativeDisplayList()) {
+ return nGetRotationX(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the rotation value for the display list around the Y axis
@@ -494,14 +661,23 @@
* @see View#setRotationY(float)
* @see #getRotationY()
*/
- public abstract void setRotationY(float rotationY);
+ public void setRotationY(float rotationY) {
+ if (hasNativeDisplayList()) {
+ nSetRotationY(mFinalizer.mNativeDisplayList, rotationY);
+ }
+ }
/**
* Returns the rotation value for this display list around the Y axis, in degrees.
*
* @see #setRotationY(float)
*/
- public abstract float getRotationY();
+ public float getRotationY() {
+ if (hasNativeDisplayList()) {
+ return nGetRotationY(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the scale value for the display list on the X axis
@@ -511,14 +687,23 @@
* @see View#setScaleX(float)
* @see #getScaleX()
*/
- public abstract void setScaleX(float scaleX);
+ public void setScaleX(float scaleX) {
+ if (hasNativeDisplayList()) {
+ nSetScaleX(mFinalizer.mNativeDisplayList, scaleX);
+ }
+ }
/**
* Returns the scale value for this display list on the X axis.
*
* @see #setScaleX(float)
*/
- public abstract float getScaleX();
+ public float getScaleX() {
+ if (hasNativeDisplayList()) {
+ return nGetScaleX(mFinalizer.mNativeDisplayList);
+ }
+ return 1.0f;
+ }
/**
* Sets the scale value for the display list on the Y axis
@@ -528,14 +713,23 @@
* @see View#setScaleY(float)
* @see #getScaleY()
*/
- public abstract void setScaleY(float scaleY);
+ public void setScaleY(float scaleY) {
+ if (hasNativeDisplayList()) {
+ nSetScaleY(mFinalizer.mNativeDisplayList, scaleY);
+ }
+ }
/**
* Returns the scale value for this display list on the Y axis.
*
* @see #setScaleY(float)
*/
- public abstract float getScaleY();
+ public float getScaleY() {
+ if (hasNativeDisplayList()) {
+ return nGetScaleY(mFinalizer.mNativeDisplayList);
+ }
+ return 1.0f;
+ }
/**
* Sets all of the transform-related values of the display list
@@ -551,9 +745,15 @@
*
* @hide
*/
- public abstract void setTransformationInfo(float alpha,
+ public void setTransformationInfo(float alpha,
float translationX, float translationY, float translationZ,
- float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
+ float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+ if (hasNativeDisplayList()) {
+ nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha,
+ translationX, translationY, translationZ,
+ rotation, rotationX, rotationY, scaleX, scaleY);
+ }
+ }
/**
* Sets the pivot value for the display list on the X axis
@@ -563,14 +763,23 @@
* @see View#setPivotX(float)
* @see #getPivotX()
*/
- public abstract void setPivotX(float pivotX);
+ public void setPivotX(float pivotX) {
+ if (hasNativeDisplayList()) {
+ nSetPivotX(mFinalizer.mNativeDisplayList, pivotX);
+ }
+ }
/**
* Returns the pivot value for this display list on the X axis, in pixels.
*
* @see #setPivotX(float)
*/
- public abstract float getPivotX();
+ public float getPivotX() {
+ if (hasNativeDisplayList()) {
+ return nGetPivotX(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the pivot value for the display list on the Y axis
@@ -580,14 +789,23 @@
* @see View#setPivotY(float)
* @see #getPivotY()
*/
- public abstract void setPivotY(float pivotY);
+ public void setPivotY(float pivotY) {
+ if (hasNativeDisplayList()) {
+ nSetPivotY(mFinalizer.mNativeDisplayList, pivotY);
+ }
+ }
/**
* Returns the pivot value for this display list on the Y axis, in pixels.
*
* @see #setPivotY(float)
*/
- public abstract float getPivotY();
+ public float getPivotY() {
+ if (hasNativeDisplayList()) {
+ return nGetPivotY(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the camera distance for the display list. Refer to
@@ -599,14 +817,23 @@
* @see View#setCameraDistance(float)
* @see #getCameraDistance()
*/
- public abstract void setCameraDistance(float distance);
+ public void setCameraDistance(float distance) {
+ if (hasNativeDisplayList()) {
+ nSetCameraDistance(mFinalizer.mNativeDisplayList, distance);
+ }
+ }
/**
* Returns the distance in Z of the camera of the display list.
*
* @see #setCameraDistance(float)
*/
- public abstract float getCameraDistance();
+ public float getCameraDistance() {
+ if (hasNativeDisplayList()) {
+ return nGetCameraDistance(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the left position for the display list.
@@ -616,14 +843,23 @@
* @see View#setLeft(int)
* @see #getLeft()
*/
- public abstract void setLeft(int left);
+ public void setLeft(int left) {
+ if (hasNativeDisplayList()) {
+ nSetLeft(mFinalizer.mNativeDisplayList, left);
+ }
+ }
/**
* Returns the left position for the display list in pixels.
*
* @see #setLeft(int)
*/
- public abstract float getLeft();
+ public float getLeft() {
+ if (hasNativeDisplayList()) {
+ return nGetLeft(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the top position for the display list.
@@ -633,14 +869,23 @@
* @see View#setTop(int)
* @see #getTop()
*/
- public abstract void setTop(int top);
+ public void setTop(int top) {
+ if (hasNativeDisplayList()) {
+ nSetTop(mFinalizer.mNativeDisplayList, top);
+ }
+ }
/**
* Returns the top position for the display list in pixels.
*
* @see #setTop(int)
*/
- public abstract float getTop();
+ public float getTop() {
+ if (hasNativeDisplayList()) {
+ return nGetTop(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the right position for the display list.
@@ -650,14 +895,23 @@
* @see View#setRight(int)
* @see #getRight()
*/
- public abstract void setRight(int right);
+ public void setRight(int right) {
+ if (hasNativeDisplayList()) {
+ nSetRight(mFinalizer.mNativeDisplayList, right);
+ }
+ }
/**
* Returns the right position for the display list in pixels.
*
* @see #setRight(int)
*/
- public abstract float getRight();
+ public float getRight() {
+ if (hasNativeDisplayList()) {
+ return nGetRight(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the bottom position for the display list.
@@ -667,14 +921,23 @@
* @see View#setBottom(int)
* @see #getBottom()
*/
- public abstract void setBottom(int bottom);
+ public void setBottom(int bottom) {
+ if (hasNativeDisplayList()) {
+ nSetBottom(mFinalizer.mNativeDisplayList, bottom);
+ }
+ }
/**
* Returns the bottom position for the display list in pixels.
*
* @see #setBottom(int)
*/
- public abstract float getBottom();
+ public float getBottom() {
+ if (hasNativeDisplayList()) {
+ return nGetBottom(mFinalizer.mNativeDisplayList);
+ }
+ return 0.0f;
+ }
/**
* Sets the left and top positions for the display list
@@ -689,7 +952,11 @@
* @see View#setRight(int)
* @see View#setBottom(int)
*/
- public abstract void setLeftTopRightBottom(int left, int top, int right, int bottom);
+ public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+ if (hasNativeDisplayList()) {
+ nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom);
+ }
+ }
/**
* Offsets the left and right positions for the display list
@@ -699,7 +966,11 @@
*
* @see View#offsetLeftAndRight(int)
*/
- public abstract void offsetLeftAndRight(float offset);
+ public void offsetLeftAndRight(float offset) {
+ if (hasNativeDisplayList()) {
+ nOffsetLeftAndRight(mFinalizer.mNativeDisplayList, offset);
+ }
+ }
/**
* Offsets the top and bottom values for the display list
@@ -709,7 +980,11 @@
*
* @see View#offsetTopAndBottom(int)
*/
- public abstract void offsetTopAndBottom(float offset);
+ public void offsetTopAndBottom(float offset) {
+ if (hasNativeDisplayList()) {
+ nOffsetTopAndBottom(mFinalizer.mNativeDisplayList, offset);
+ }
+ }
/**
* Outputs the display list to the log. This method exists for use by
@@ -717,5 +992,91 @@
*
* @hide
*/
- public abstract void output();
+ public void output() {
+ if (hasNativeDisplayList()) {
+ nOutput(mFinalizer.mNativeDisplayList);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Native methods
+ ///////////////////////////////////////////////////////////////////////////
+
+ private static native void nDestroyDisplayList(int displayList);
+ private static native int nGetDisplayListSize(int displayList);
+ private static native void nSetDisplayListName(int displayList, String name);
+
+ // Properties
+
+ private static native void nReset(int displayList);
+ private static native void nOffsetTopAndBottom(int displayList, float offset);
+ private static native void nOffsetLeftAndRight(int displayList, float offset);
+ private static native void nSetLeftTopRightBottom(int displayList, int left, int top,
+ int right, int bottom);
+ private static native void nSetBottom(int displayList, int bottom);
+ private static native void nSetRight(int displayList, int right);
+ private static native void nSetTop(int displayList, int top);
+ private static native void nSetLeft(int displayList, int left);
+ private static native void nSetCameraDistance(int displayList, float distance);
+ private static native void nSetPivotY(int displayList, float pivotY);
+ private static native void nSetPivotX(int displayList, float pivotX);
+ private static native void nSetCaching(int displayList, boolean caching);
+ private static native void nSetClipToBounds(int displayList, boolean clipToBounds);
+ private static native void nSetAlpha(int displayList, float alpha);
+ private static native void nSetHasOverlappingRendering(int displayList,
+ boolean hasOverlappingRendering);
+ private static native void nSetTranslationX(int displayList, float translationX);
+ private static native void nSetTranslationY(int displayList, float translationY);
+ private static native void nSetTranslationZ(int displayList, float translationZ);
+ private static native void nSetRotation(int displayList, float rotation);
+ private static native void nSetRotationX(int displayList, float rotationX);
+ private static native void nSetRotationY(int displayList, float rotationY);
+ private static native void nSetScaleX(int displayList, float scaleX);
+ private static native void nSetScaleY(int displayList, float scaleY);
+ private static native void nSetTransformationInfo(int displayList, float alpha,
+ float translationX, float translationY, float translationZ,
+ float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
+ private static native void nSetStaticMatrix(int displayList, int nativeMatrix);
+ private static native void nSetAnimationMatrix(int displayList, int animationMatrix);
+
+ private static native boolean nHasOverlappingRendering(int displayList);
+ private static native void nGetMatrix(int displayList, int matrix);
+ private static native float nGetAlpha(int displayList);
+ private static native float nGetLeft(int displayList);
+ private static native float nGetTop(int displayList);
+ private static native float nGetRight(int displayList);
+ private static native float nGetBottom(int displayList);
+ private static native float nGetCameraDistance(int displayList);
+ private static native float nGetScaleX(int displayList);
+ private static native float nGetScaleY(int displayList);
+ private static native float nGetTranslationX(int displayList);
+ private static native float nGetTranslationY(int displayList);
+ private static native float nGetTranslationZ(int displayList);
+ private static native float nGetRotation(int displayList);
+ private static native float nGetRotationX(int displayList);
+ private static native float nGetRotationY(int displayList);
+ private static native float nGetPivotX(int displayList);
+ private static native float nGetPivotY(int displayList);
+ private static native void nOutput(int displayList);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Finalization
+ ///////////////////////////////////////////////////////////////////////////
+
+ private static class DisplayListFinalizer {
+ final int mNativeDisplayList;
+
+ public DisplayListFinalizer(int nativeDisplayList) {
+ mNativeDisplayList = nativeDisplayList;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ nDestroyDisplayList(mNativeDisplayList);
+ } finally {
+ super.finalize();
+ }
+ }
+ }
}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 9b48881d..584a04c 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -416,7 +416,7 @@
@Override
public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
- return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList(),
+ return nDrawDisplayList(mRenderer, displayList.getNativeDisplayList(),
dirty, flags);
}
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
deleted file mode 100644
index 7944e66..0000000
--- a/core/java/android/view/GLES20DisplayList.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.graphics.Matrix;
-
-import java.util.ArrayList;
-
-/**
- * An implementation of display list for OpenGL ES 2.0.
- */
-class GLES20DisplayList extends DisplayList {
- private ArrayList<DisplayList> mChildDisplayLists;
-
- private GLES20RecordingCanvas mCanvas;
- private boolean mValid;
-
- // Used for debugging
- private final String mName;
-
- // The native display list will be destroyed when this object dies.
- // DO NOT overwrite this reference once it is set.
- private DisplayListFinalizer mFinalizer;
-
- GLES20DisplayList(String name) {
- mName = name;
- }
-
- boolean hasNativeDisplayList() {
- return mValid && mFinalizer != null;
- }
-
- int getNativeDisplayList() {
- if (!mValid || mFinalizer == null) {
- throw new IllegalStateException("The display list is not valid.");
- }
- return mFinalizer.mNativeDisplayList;
- }
-
- @Override
- public HardwareCanvas start(int width, int height) {
- if (mCanvas != null) {
- throw new IllegalStateException("Recording has already started");
- }
-
- mValid = false;
- mCanvas = GLES20RecordingCanvas.obtain(this);
- mCanvas.start();
-
- mCanvas.setViewport(width, height);
- // The dirty rect should always be null for a display list
- mCanvas.onPreDraw(null);
-
- return mCanvas;
- }
- @Override
- public void clear() {
- clearDirty();
-
- if (mCanvas != null) {
- mCanvas.recycle();
- mCanvas = null;
- }
- mValid = false;
-
- clearReferences();
- }
-
- void clearReferences() {
- if (mChildDisplayLists != null) mChildDisplayLists.clear();
- }
-
- ArrayList<DisplayList> getChildDisplayLists() {
- if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>();
- return mChildDisplayLists;
- }
-
- @Override
- public void reset() {
- if (hasNativeDisplayList()) {
- nReset(mFinalizer.mNativeDisplayList);
- }
- clear();
- }
-
- @Override
- public boolean isValid() {
- return mValid;
- }
-
- @Override
- public void end() {
- if (mCanvas != null) {
- mCanvas.onPostDraw();
- if (mFinalizer != null) {
- mCanvas.end(mFinalizer.mNativeDisplayList);
- } else {
- mFinalizer = new DisplayListFinalizer(mCanvas.end(0));
- nSetDisplayListName(mFinalizer.mNativeDisplayList, mName);
- }
- mCanvas.recycle();
- mCanvas = null;
- mValid = true;
- }
- }
-
- @Override
- public int getSize() {
- if (mFinalizer == null) return 0;
- return nGetDisplayListSize(mFinalizer.mNativeDisplayList);
- }
-
- private static native void nDestroyDisplayList(int displayList);
- private static native int nGetDisplayListSize(int displayList);
- private static native void nSetDisplayListName(int displayList, String name);
-
- ///////////////////////////////////////////////////////////////////////////
- // Native View Properties
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- public void setCaching(boolean caching) {
- if (hasNativeDisplayList()) {
- nSetCaching(mFinalizer.mNativeDisplayList, caching);
- }
- }
-
- @Override
- public void setClipToBounds(boolean clipToBounds) {
- if (hasNativeDisplayList()) {
- nSetClipToBounds(mFinalizer.mNativeDisplayList, clipToBounds);
- }
- }
-
- @Override
- public void setMatrix(Matrix matrix) {
- if (hasNativeDisplayList()) {
- nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
- }
- }
-
- @Override
- public Matrix getMatrix(Matrix matrix) {
- if (hasNativeDisplayList()) {
- nGetMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
- }
- return matrix;
- }
-
- @Override
- public void setAnimationMatrix(Matrix matrix) {
- if (hasNativeDisplayList()) {
- nSetAnimationMatrix(mFinalizer.mNativeDisplayList,
- (matrix != null) ? matrix.native_instance : 0);
- }
- }
-
- @Override
- public void setAlpha(float alpha) {
- if (hasNativeDisplayList()) {
- nSetAlpha(mFinalizer.mNativeDisplayList, alpha);
- }
- }
-
- @Override
- public float getAlpha() {
- if (hasNativeDisplayList()) {
- return nGetAlpha(mFinalizer.mNativeDisplayList);
- }
- return 1.0f;
- }
-
- @Override
- public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
- if (hasNativeDisplayList()) {
- nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering);
- }
- }
-
- @Override
- public boolean hasOverlappingRendering() {
- //noinspection SimplifiableIfStatement
- if (hasNativeDisplayList()) {
- return nHasOverlappingRendering(mFinalizer.mNativeDisplayList);
- }
- return true;
- }
-
- @Override
- public void setTranslationX(float translationX) {
- if (hasNativeDisplayList()) {
- nSetTranslationX(mFinalizer.mNativeDisplayList, translationX);
- }
- }
-
- @Override
- public float getTranslationX() {
- if (hasNativeDisplayList()) {
- return nGetTranslationX(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setTranslationY(float translationY) {
- if (hasNativeDisplayList()) {
- nSetTranslationY(mFinalizer.mNativeDisplayList, translationY);
- }
- }
-
- @Override
- public float getTranslationY() {
- if (hasNativeDisplayList()) {
- return nGetTranslationY(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setTranslationZ(float translationZ) {
- if (hasNativeDisplayList()) {
- nSetTranslationZ(mFinalizer.mNativeDisplayList, translationZ);
- }
- }
-
- @Override
- public float getTranslationZ() {
- if (hasNativeDisplayList()) {
- return nGetTranslationZ(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setRotation(float rotation) {
- if (hasNativeDisplayList()) {
- nSetRotation(mFinalizer.mNativeDisplayList, rotation);
- }
- }
-
- @Override
- public float getRotation() {
- if (hasNativeDisplayList()) {
- return nGetRotation(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setRotationX(float rotationX) {
- if (hasNativeDisplayList()) {
- nSetRotationX(mFinalizer.mNativeDisplayList, rotationX);
- }
- }
-
- @Override
- public float getRotationX() {
- if (hasNativeDisplayList()) {
- return nGetRotationX(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setRotationY(float rotationY) {
- if (hasNativeDisplayList()) {
- nSetRotationY(mFinalizer.mNativeDisplayList, rotationY);
- }
- }
-
- @Override
- public float getRotationY() {
- if (hasNativeDisplayList()) {
- return nGetRotationY(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setScaleX(float scaleX) {
- if (hasNativeDisplayList()) {
- nSetScaleX(mFinalizer.mNativeDisplayList, scaleX);
- }
- }
-
- @Override
- public float getScaleX() {
- if (hasNativeDisplayList()) {
- return nGetScaleX(mFinalizer.mNativeDisplayList);
- }
- return 1.0f;
- }
-
- @Override
- public void setScaleY(float scaleY) {
- if (hasNativeDisplayList()) {
- nSetScaleY(mFinalizer.mNativeDisplayList, scaleY);
- }
- }
-
- @Override
- public float getScaleY() {
- if (hasNativeDisplayList()) {
- return nGetScaleY(mFinalizer.mNativeDisplayList);
- }
- return 1.0f;
- }
-
- @Override
- public void setTransformationInfo(float alpha,
- float translationX, float translationY, float translationZ,
- float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
- if (hasNativeDisplayList()) {
- nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha,
- translationX, translationY, translationZ,
- rotation, rotationX, rotationY, scaleX, scaleY);
- }
- }
-
- @Override
- public void setPivotX(float pivotX) {
- if (hasNativeDisplayList()) {
- nSetPivotX(mFinalizer.mNativeDisplayList, pivotX);
- }
- }
-
- @Override
- public float getPivotX() {
- if (hasNativeDisplayList()) {
- return nGetPivotX(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setPivotY(float pivotY) {
- if (hasNativeDisplayList()) {
- nSetPivotY(mFinalizer.mNativeDisplayList, pivotY);
- }
- }
-
- @Override
- public float getPivotY() {
- if (hasNativeDisplayList()) {
- return nGetPivotY(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setCameraDistance(float distance) {
- if (hasNativeDisplayList()) {
- nSetCameraDistance(mFinalizer.mNativeDisplayList, distance);
- }
- }
-
- @Override
- public float getCameraDistance() {
- if (hasNativeDisplayList()) {
- return nGetCameraDistance(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setLeft(int left) {
- if (hasNativeDisplayList()) {
- nSetLeft(mFinalizer.mNativeDisplayList, left);
- }
- }
-
- @Override
- public float getLeft() {
- if (hasNativeDisplayList()) {
- return nGetLeft(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setTop(int top) {
- if (hasNativeDisplayList()) {
- nSetTop(mFinalizer.mNativeDisplayList, top);
- }
- }
-
- @Override
- public float getTop() {
- if (hasNativeDisplayList()) {
- return nGetTop(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setRight(int right) {
- if (hasNativeDisplayList()) {
- nSetRight(mFinalizer.mNativeDisplayList, right);
- }
- }
-
- @Override
- public float getRight() {
- if (hasNativeDisplayList()) {
- return nGetRight(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setBottom(int bottom) {
- if (hasNativeDisplayList()) {
- nSetBottom(mFinalizer.mNativeDisplayList, bottom);
- }
- }
-
- @Override
- public float getBottom() {
- if (hasNativeDisplayList()) {
- return nGetBottom(mFinalizer.mNativeDisplayList);
- }
- return 0.0f;
- }
-
- @Override
- public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
- if (hasNativeDisplayList()) {
- nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom);
- }
- }
-
- @Override
- public void offsetLeftAndRight(float offset) {
- if (hasNativeDisplayList()) {
- nOffsetLeftAndRight(mFinalizer.mNativeDisplayList, offset);
- }
- }
-
- @Override
- public void offsetTopAndBottom(float offset) {
- if (hasNativeDisplayList()) {
- nOffsetTopAndBottom(mFinalizer.mNativeDisplayList, offset);
- }
- }
-
- @Override
- public void output() {
- if (hasNativeDisplayList()) {
- nOutput(mFinalizer.mNativeDisplayList);
- }
- }
-
- private static native void nReset(int displayList);
- private static native void nOffsetTopAndBottom(int displayList, float offset);
- private static native void nOffsetLeftAndRight(int displayList, float offset);
- private static native void nSetLeftTopRightBottom(int displayList, int left, int top,
- int right, int bottom);
- private static native void nSetBottom(int displayList, int bottom);
- private static native void nSetRight(int displayList, int right);
- private static native void nSetTop(int displayList, int top);
- private static native void nSetLeft(int displayList, int left);
- private static native void nSetCameraDistance(int displayList, float distance);
- private static native void nSetPivotY(int displayList, float pivotY);
- private static native void nSetPivotX(int displayList, float pivotX);
- private static native void nSetCaching(int displayList, boolean caching);
- private static native void nSetClipToBounds(int displayList, boolean clipToBounds);
- private static native void nSetAlpha(int displayList, float alpha);
- private static native void nSetHasOverlappingRendering(int displayList,
- boolean hasOverlappingRendering);
- private static native void nSetTranslationX(int displayList, float translationX);
- private static native void nSetTranslationY(int displayList, float translationY);
- private static native void nSetTranslationZ(int displayList, float translationZ);
- private static native void nSetRotation(int displayList, float rotation);
- private static native void nSetRotationX(int displayList, float rotationX);
- private static native void nSetRotationY(int displayList, float rotationY);
- private static native void nSetScaleX(int displayList, float scaleX);
- private static native void nSetScaleY(int displayList, float scaleY);
- private static native void nSetTransformationInfo(int displayList, float alpha,
- float translationX, float translationY, float translationZ,
- float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
- private static native void nSetStaticMatrix(int displayList, int nativeMatrix);
- private static native void nSetAnimationMatrix(int displayList, int animationMatrix);
-
- private static native boolean nHasOverlappingRendering(int displayList);
- private static native void nGetMatrix(int displayList, int matrix);
- private static native float nGetAlpha(int displayList);
- private static native float nGetLeft(int displayList);
- private static native float nGetTop(int displayList);
- private static native float nGetRight(int displayList);
- private static native float nGetBottom(int displayList);
- private static native float nGetCameraDistance(int displayList);
- private static native float nGetScaleX(int displayList);
- private static native float nGetScaleY(int displayList);
- private static native float nGetTranslationX(int displayList);
- private static native float nGetTranslationY(int displayList);
- private static native float nGetTranslationZ(int displayList);
- private static native float nGetRotation(int displayList);
- private static native float nGetRotationX(int displayList);
- private static native float nGetRotationY(int displayList);
- private static native float nGetPivotX(int displayList);
- private static native float nGetPivotY(int displayList);
- private static native void nOutput(int displayList);
-
- ///////////////////////////////////////////////////////////////////////////
- // Finalization
- ///////////////////////////////////////////////////////////////////////////
-
- private static class DisplayListFinalizer {
- final int mNativeDisplayList;
-
- public DisplayListFinalizer(int nativeDisplayList) {
- mNativeDisplayList = nativeDisplayList;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- nDestroyDisplayList(mNativeDisplayList);
- } finally {
- super.finalize();
- }
- }
- }
-}
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index b6fc38d..97efa18 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -33,13 +33,13 @@
private static final SynchronizedPool<GLES20RecordingCanvas> sPool =
new SynchronizedPool<GLES20RecordingCanvas>(POOL_LIMIT);
- private GLES20DisplayList mDisplayList;
+ private DisplayList mDisplayList;
private GLES20RecordingCanvas() {
super(true, true);
}
- static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
+ static GLES20RecordingCanvas obtain(DisplayList displayList) {
GLES20RecordingCanvas canvas = sPool.acquire();
if (canvas == null) {
canvas = new GLES20RecordingCanvas();
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
index 68ba77c..8c97867 100644
--- a/core/java/android/view/GLES20RenderLayer.java
+++ b/core/java/android/view/GLES20RenderLayer.java
@@ -124,7 +124,7 @@
@Override
void redrawLater(DisplayList displayList, Rect dirtyRect) {
GLES20Canvas.nUpdateRenderLayer(mLayer, mCanvas.getRenderer(),
- ((GLES20DisplayList) displayList).getNativeDisplayList(),
+ displayList.getNativeDisplayList(),
dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
}
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 329331a..f26374a 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -42,6 +42,7 @@
android_database_SQLiteDebug.cpp \
android_emoji_EmojiFactory.cpp \
android_view_DisplayEventReceiver.cpp \
+ android_view_DisplayList.cpp \
android_view_Surface.cpp \
android_view_SurfaceControl.cpp \
android_view_SurfaceSession.cpp \
@@ -55,7 +56,6 @@
android_view_KeyCharacterMap.cpp \
android_view_GraphicBuffer.cpp \
android_view_GLRenderer.cpp \
- android_view_GLES20DisplayList.cpp \
android_view_GLES20Canvas.cpp \
android_view_ThreadedRenderer.cpp \
android_view_MotionEvent.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index b20dc09..89d75dc 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -119,8 +119,8 @@
extern int register_android_graphics_Xfermode(JNIEnv* env);
extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
+extern int register_android_view_DisplayList(JNIEnv* env);
extern int register_android_view_GraphicBuffer(JNIEnv* env);
-extern int register_android_view_GLES20DisplayList(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
extern int register_android_view_GLRenderer(JNIEnv* env);
extern int register_android_view_ThreadedRenderer(JNIEnv* env);
@@ -1121,11 +1121,11 @@
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
- REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_nio_utils),
REG_JNI(register_android_graphics_Graphics),
+ REG_JNI(register_android_view_DisplayEventReceiver),
+ REG_JNI(register_android_view_DisplayList),
REG_JNI(register_android_view_GraphicBuffer),
- REG_JNI(register_android_view_GLES20DisplayList),
REG_JNI(register_android_view_GLES20Canvas),
REG_JNI(register_android_view_GLRenderer),
REG_JNI(register_android_view_ThreadedRenderer),
diff --git a/core/jni/android_view_DisplayList.cpp b/core/jni/android_view_DisplayList.cpp
new file mode 100644
index 0000000..fc12ec4
--- /dev/null
+++ b/core/jni/android_view_DisplayList.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <EGL/egl.h>
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <DisplayList.h>
+#include <DisplayListRenderer.h>
+
+namespace android {
+
+using namespace uirenderer;
+
+/**
+ * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
+ * devices. This means all the logic must be compiled only when the
+ * preprocessor variable USE_OPENGL_RENDERER is defined.
+ */
+#ifdef USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// DisplayList view properties
+// ----------------------------------------------------------------------------
+
+static void android_view_DisplayList_reset(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ displayList->reset();
+}
+
+static jint android_view_DisplayList_getDisplayListSize(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getSize();
+}
+
+static void android_view_DisplayList_setDisplayListName(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, jstring name) {
+ if (name != NULL) {
+ const char* textArray = env->GetStringUTFChars(name, NULL);
+ displayList->setName(textArray);
+ env->ReleaseStringUTFChars(name, textArray);
+ }
+}
+
+static void android_view_DisplayList_output(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ displayList->output();
+}
+
+static void android_view_DisplayList_destroyDisplayList(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ DisplayList::destroyDisplayListDeferred(displayList);
+}
+
+// ----------------------------------------------------------------------------
+// DisplayList view properties
+// ----------------------------------------------------------------------------
+
+static void android_view_DisplayList_setCaching(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, jboolean caching) {
+ displayList->setCaching(caching);
+}
+
+static void android_view_DisplayList_setStaticMatrix(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
+ displayList->setStaticMatrix(matrix);
+}
+
+static void android_view_DisplayList_setAnimationMatrix(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
+ displayList->setAnimationMatrix(matrix);
+}
+
+static void android_view_DisplayList_setClipToBounds(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, jboolean clipToBounds) {
+ displayList->setClipToBounds(clipToBounds);
+}
+
+static void android_view_DisplayList_setAlpha(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float alpha) {
+ displayList->setAlpha(alpha);
+}
+
+static void android_view_DisplayList_setHasOverlappingRendering(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, bool hasOverlappingRendering) {
+ displayList->setHasOverlappingRendering(hasOverlappingRendering);
+}
+
+static void android_view_DisplayList_setTranslationX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float tx) {
+ displayList->setTranslationX(tx);
+}
+
+static void android_view_DisplayList_setTranslationY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float ty) {
+ displayList->setTranslationY(ty);
+}
+
+static void android_view_DisplayList_setTranslationZ(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float tz) {
+ displayList->setTranslationZ(tz);
+}
+
+static void android_view_DisplayList_setRotation(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float rotation) {
+ displayList->setRotation(rotation);
+}
+
+static void android_view_DisplayList_setRotationX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float rx) {
+ displayList->setRotationX(rx);
+}
+
+static void android_view_DisplayList_setRotationY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float ry) {
+ displayList->setRotationY(ry);
+}
+
+static void android_view_DisplayList_setScaleX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float sx) {
+ displayList->setScaleX(sx);
+}
+
+static void android_view_DisplayList_setScaleY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float sy) {
+ displayList->setScaleY(sy);
+}
+
+static void android_view_DisplayList_setTransformationInfo(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float alpha,
+ float translationX, float translationY, float translationZ,
+ float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+ displayList->setAlpha(alpha);
+ displayList->setTranslationX(translationX);
+ displayList->setTranslationY(translationY);
+ displayList->setTranslationZ(translationZ);
+ displayList->setRotation(rotation);
+ displayList->setRotationX(rotationX);
+ displayList->setRotationY(rotationY);
+ displayList->setScaleX(scaleX);
+ displayList->setScaleY(scaleY);
+}
+
+static void android_view_DisplayList_setPivotX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float px) {
+ displayList->setPivotX(px);
+}
+
+static void android_view_DisplayList_setPivotY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float py) {
+ displayList->setPivotY(py);
+}
+
+static void android_view_DisplayList_setCameraDistance(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float distance) {
+ displayList->setCameraDistance(distance);
+}
+
+static void android_view_DisplayList_setLeft(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int left) {
+ displayList->setLeft(left);
+}
+
+static void android_view_DisplayList_setTop(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int top) {
+ displayList->setTop(top);
+}
+
+static void android_view_DisplayList_setRight(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int right) {
+ displayList->setRight(right);
+}
+
+static void android_view_DisplayList_setBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int bottom) {
+ displayList->setBottom(bottom);
+}
+
+static void android_view_DisplayList_setLeftTopRightBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, int left, int top,
+ int right, int bottom) {
+ displayList->setLeftTopRightBottom(left, top, right, bottom);
+}
+
+static void android_view_DisplayList_offsetLeftAndRight(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float offset) {
+ displayList->offsetLeftRight(offset);
+}
+
+static void android_view_DisplayList_offsetTopAndBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, float offset) {
+ displayList->offsetTopBottom(offset);
+}
+
+static void android_view_DisplayList_getMatrix(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
+ SkMatrix* source = displayList->getStaticMatrix();
+ if (source) {
+ matrix->setConcat(SkMatrix::I(), *source);
+ } else {
+ matrix->setIdentity();
+ }
+}
+
+static jboolean android_view_DisplayList_hasOverlappingRendering(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->hasOverlappingRendering();
+}
+
+static jfloat android_view_DisplayList_getAlpha(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getAlpha();
+}
+
+static jfloat android_view_DisplayList_getLeft(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getLeft();
+}
+
+static jfloat android_view_DisplayList_getTop(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getTop();
+}
+
+static jfloat android_view_DisplayList_getRight(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getRight();
+}
+
+static jfloat android_view_DisplayList_getBottom(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getBottom();
+}
+
+static jfloat android_view_DisplayList_getCameraDistance(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getCameraDistance();
+}
+
+static jfloat android_view_DisplayList_getScaleX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getScaleX();
+}
+
+static jfloat android_view_DisplayList_getScaleY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getScaleY();
+}
+
+static jfloat android_view_DisplayList_getTranslationX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getTranslationX();
+}
+
+static jfloat android_view_DisplayList_getTranslationY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getTranslationY();
+}
+
+static jfloat android_view_DisplayList_getRotation(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getRotation();
+}
+
+static jfloat android_view_DisplayList_getRotationX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getRotationX();
+}
+
+static jfloat android_view_DisplayList_getRotationY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getRotationY();
+}
+
+static jfloat android_view_DisplayList_getPivotX(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getPivotX();
+}
+
+static jfloat android_view_DisplayList_getPivotY(JNIEnv* env,
+ jobject clazz, DisplayList* displayList) {
+ return displayList->getPivotY();
+}
+
+#endif // USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/DisplayList";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+ { "nDestroyDisplayList", "(I)V", (void*) android_view_DisplayList_destroyDisplayList },
+ { "nGetDisplayListSize", "(I)I", (void*) android_view_DisplayList_getDisplayListSize },
+ { "nSetDisplayListName", "(ILjava/lang/String;)V",
+ (void*) android_view_DisplayList_setDisplayListName },
+ { "nOutput", "(I)V", (void*) android_view_DisplayList_output },
+
+ { "nReset", "(I)V", (void*) android_view_DisplayList_reset },
+ { "nSetCaching", "(IZ)V", (void*) android_view_DisplayList_setCaching },
+ { "nSetStaticMatrix", "(II)V", (void*) android_view_DisplayList_setStaticMatrix },
+ { "nSetAnimationMatrix", "(II)V", (void*) android_view_DisplayList_setAnimationMatrix },
+ { "nSetClipToBounds", "(IZ)V", (void*) android_view_DisplayList_setClipToBounds },
+ { "nSetAlpha", "(IF)V", (void*) android_view_DisplayList_setAlpha },
+ { "nSetHasOverlappingRendering", "(IZ)V",
+ (void*) android_view_DisplayList_setHasOverlappingRendering },
+ { "nSetTranslationX", "(IF)V", (void*) android_view_DisplayList_setTranslationX },
+ { "nSetTranslationY", "(IF)V", (void*) android_view_DisplayList_setTranslationY },
+ { "nSetTranslationZ", "(IF)V", (void*) android_view_DisplayList_setTranslationZ },
+ { "nSetRotation", "(IF)V", (void*) android_view_DisplayList_setRotation },
+ { "nSetRotationX", "(IF)V", (void*) android_view_DisplayList_setRotationX },
+ { "nSetRotationY", "(IF)V", (void*) android_view_DisplayList_setRotationY },
+ { "nSetScaleX", "(IF)V", (void*) android_view_DisplayList_setScaleX },
+ { "nSetScaleY", "(IF)V", (void*) android_view_DisplayList_setScaleY },
+ { "nSetTransformationInfo","(IFFFFFFFFF)V",
+ (void*) android_view_DisplayList_setTransformationInfo },
+ { "nSetPivotX", "(IF)V", (void*) android_view_DisplayList_setPivotX },
+ { "nSetPivotY", "(IF)V", (void*) android_view_DisplayList_setPivotY },
+ { "nSetCameraDistance", "(IF)V", (void*) android_view_DisplayList_setCameraDistance },
+ { "nSetLeft", "(II)V", (void*) android_view_DisplayList_setLeft },
+ { "nSetTop", "(II)V", (void*) android_view_DisplayList_setTop },
+ { "nSetRight", "(II)V", (void*) android_view_DisplayList_setRight },
+ { "nSetBottom", "(II)V", (void*) android_view_DisplayList_setBottom },
+ { "nSetLeftTopRightBottom","(IIIII)V", (void*) android_view_DisplayList_setLeftTopRightBottom },
+ { "nOffsetLeftAndRight", "(IF)V", (void*) android_view_DisplayList_offsetLeftAndRight },
+ { "nOffsetTopAndBottom", "(IF)V", (void*) android_view_DisplayList_offsetTopAndBottom },
+
+ { "nGetMatrix", "(II)V", (void*) android_view_DisplayList_getMatrix },
+ { "nHasOverlappingRendering", "(I)Z", (void*) android_view_DisplayList_hasOverlappingRendering },
+ { "nGetAlpha", "(I)F", (void*) android_view_DisplayList_getAlpha },
+ { "nGetLeft", "(I)F", (void*) android_view_DisplayList_getLeft },
+ { "nGetTop", "(I)F", (void*) android_view_DisplayList_getTop },
+ { "nGetRight", "(I)F", (void*) android_view_DisplayList_getRight },
+ { "nGetBottom", "(I)F", (void*) android_view_DisplayList_getBottom },
+ { "nGetCameraDistance", "(I)F", (void*) android_view_DisplayList_getCameraDistance },
+ { "nGetScaleX", "(I)F", (void*) android_view_DisplayList_getScaleX },
+ { "nGetScaleY", "(I)F", (void*) android_view_DisplayList_getScaleY },
+ { "nGetTranslationX", "(I)F", (void*) android_view_DisplayList_getTranslationX },
+ { "nGetTranslationY", "(I)F", (void*) android_view_DisplayList_getTranslationY },
+ { "nGetRotation", "(I)F", (void*) android_view_DisplayList_getRotation },
+ { "nGetRotationX", "(I)F", (void*) android_view_DisplayList_getRotationX },
+ { "nGetRotationY", "(I)F", (void*) android_view_DisplayList_getRotationY },
+ { "nGetPivotX", "(I)F", (void*) android_view_DisplayList_getPivotX },
+ { "nGetPivotY", "(I)F", (void*) android_view_DisplayList_getPivotY },
+#endif
+};
+
+#ifdef USE_OPENGL_RENDERER
+ #define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className);
+
+ #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+ var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find method " methodName);
+#else
+ #define FIND_CLASS(var, className)
+ #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
+#endif
+
+int register_android_view_DisplayList(JNIEnv* env) {
+ return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
+
diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp
deleted file mode 100644
index d6cddb2..0000000
--- a/core/jni/android_view_GLES20DisplayList.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "OpenGLRenderer"
-
-#include <EGL/egl.h>
-
-#include "jni.h"
-#include "GraphicsJNI.h"
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <DisplayList.h>
-#include <DisplayListRenderer.h>
-
-namespace android {
-
-using namespace uirenderer;
-
-/**
- * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
- * devices. This means all the logic must be compiled only when the
- * preprocessor variable USE_OPENGL_RENDERER is defined.
- */
-#ifdef USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// DisplayList view properties
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20DisplayList_reset(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- displayList->reset();
-}
-
-static jint android_view_GLES20DisplayList_getDisplayListSize(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getSize();
-}
-
-static void android_view_GLES20DisplayList_setDisplayListName(JNIEnv* env,
- jobject clazz, DisplayList* displayList, jstring name) {
- if (name != NULL) {
- const char* textArray = env->GetStringUTFChars(name, NULL);
- displayList->setName(textArray);
- env->ReleaseStringUTFChars(name, textArray);
- }
-}
-
-static void android_view_GLES20DisplayList_output(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- displayList->output();
-}
-
-static void android_view_GLES20DisplayList_destroyDisplayList(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- DisplayList::destroyDisplayListDeferred(displayList);
-}
-
-// ----------------------------------------------------------------------------
-// DisplayList view properties
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20DisplayList_setCaching(JNIEnv* env,
- jobject clazz, DisplayList* displayList, jboolean caching) {
- displayList->setCaching(caching);
-}
-
-static void android_view_GLES20DisplayList_setStaticMatrix(JNIEnv* env,
- jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
- displayList->setStaticMatrix(matrix);
-}
-
-static void android_view_GLES20DisplayList_setAnimationMatrix(JNIEnv* env,
- jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
- displayList->setAnimationMatrix(matrix);
-}
-
-static void android_view_GLES20DisplayList_setClipToBounds(JNIEnv* env,
- jobject clazz, DisplayList* displayList, jboolean clipToBounds) {
- displayList->setClipToBounds(clipToBounds);
-}
-
-static void android_view_GLES20DisplayList_setAlpha(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float alpha) {
- displayList->setAlpha(alpha);
-}
-
-static void android_view_GLES20DisplayList_setHasOverlappingRendering(JNIEnv* env,
- jobject clazz, DisplayList* displayList, bool hasOverlappingRendering) {
- displayList->setHasOverlappingRendering(hasOverlappingRendering);
-}
-
-static void android_view_GLES20DisplayList_setTranslationX(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float tx) {
- displayList->setTranslationX(tx);
-}
-
-static void android_view_GLES20DisplayList_setTranslationY(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float ty) {
- displayList->setTranslationY(ty);
-}
-
-static void android_view_GLES20DisplayList_setTranslationZ(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float tz) {
- displayList->setTranslationZ(tz);
-}
-
-static void android_view_GLES20DisplayList_setRotation(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float rotation) {
- displayList->setRotation(rotation);
-}
-
-static void android_view_GLES20DisplayList_setRotationX(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float rx) {
- displayList->setRotationX(rx);
-}
-
-static void android_view_GLES20DisplayList_setRotationY(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float ry) {
- displayList->setRotationY(ry);
-}
-
-static void android_view_GLES20DisplayList_setScaleX(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float sx) {
- displayList->setScaleX(sx);
-}
-
-static void android_view_GLES20DisplayList_setScaleY(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float sy) {
- displayList->setScaleY(sy);
-}
-
-static void android_view_GLES20DisplayList_setTransformationInfo(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float alpha,
- float translationX, float translationY, float translationZ,
- float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
- displayList->setAlpha(alpha);
- displayList->setTranslationX(translationX);
- displayList->setTranslationY(translationY);
- displayList->setTranslationZ(translationZ);
- displayList->setRotation(rotation);
- displayList->setRotationX(rotationX);
- displayList->setRotationY(rotationY);
- displayList->setScaleX(scaleX);
- displayList->setScaleY(scaleY);
-}
-
-static void android_view_GLES20DisplayList_setPivotX(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float px) {
- displayList->setPivotX(px);
-}
-
-static void android_view_GLES20DisplayList_setPivotY(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float py) {
- displayList->setPivotY(py);
-}
-
-static void android_view_GLES20DisplayList_setCameraDistance(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float distance) {
- displayList->setCameraDistance(distance);
-}
-
-static void android_view_GLES20DisplayList_setLeft(JNIEnv* env,
- jobject clazz, DisplayList* displayList, int left) {
- displayList->setLeft(left);
-}
-
-static void android_view_GLES20DisplayList_setTop(JNIEnv* env,
- jobject clazz, DisplayList* displayList, int top) {
- displayList->setTop(top);
-}
-
-static void android_view_GLES20DisplayList_setRight(JNIEnv* env,
- jobject clazz, DisplayList* displayList, int right) {
- displayList->setRight(right);
-}
-
-static void android_view_GLES20DisplayList_setBottom(JNIEnv* env,
- jobject clazz, DisplayList* displayList, int bottom) {
- displayList->setBottom(bottom);
-}
-
-static void android_view_GLES20DisplayList_setLeftTopRightBottom(JNIEnv* env,
- jobject clazz, DisplayList* displayList, int left, int top,
- int right, int bottom) {
- displayList->setLeftTopRightBottom(left, top, right, bottom);
-}
-
-static void android_view_GLES20DisplayList_offsetLeftAndRight(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float offset) {
- displayList->offsetLeftRight(offset);
-}
-
-static void android_view_GLES20DisplayList_offsetTopAndBottom(JNIEnv* env,
- jobject clazz, DisplayList* displayList, float offset) {
- displayList->offsetTopBottom(offset);
-}
-
-static void android_view_GLES20DisplayList_getMatrix(JNIEnv* env,
- jobject clazz, DisplayList* displayList, SkMatrix* matrix) {
- SkMatrix* source = displayList->getStaticMatrix();
- if (source) {
- matrix->setConcat(SkMatrix::I(), *source);
- } else {
- matrix->setIdentity();
- }
-}
-
-static jboolean android_view_GLES20DisplayList_hasOverlappingRendering(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->hasOverlappingRendering();
-}
-
-static jfloat android_view_GLES20DisplayList_getAlpha(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getAlpha();
-}
-
-static jfloat android_view_GLES20DisplayList_getLeft(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getLeft();
-}
-
-static jfloat android_view_GLES20DisplayList_getTop(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getTop();
-}
-
-static jfloat android_view_GLES20DisplayList_getRight(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getRight();
-}
-
-static jfloat android_view_GLES20DisplayList_getBottom(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getBottom();
-}
-
-static jfloat android_view_GLES20DisplayList_getCameraDistance(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getCameraDistance();
-}
-
-static jfloat android_view_GLES20DisplayList_getScaleX(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getScaleX();
-}
-
-static jfloat android_view_GLES20DisplayList_getScaleY(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getScaleY();
-}
-
-static jfloat android_view_GLES20DisplayList_getTranslationX(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getTranslationX();
-}
-
-static jfloat android_view_GLES20DisplayList_getTranslationY(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getTranslationY();
-}
-
-static jfloat android_view_GLES20DisplayList_getRotation(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getRotation();
-}
-
-static jfloat android_view_GLES20DisplayList_getRotationX(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getRotationX();
-}
-
-static jfloat android_view_GLES20DisplayList_getRotationY(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getRotationY();
-}
-
-static jfloat android_view_GLES20DisplayList_getPivotX(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getPivotX();
-}
-
-static jfloat android_view_GLES20DisplayList_getPivotY(JNIEnv* env,
- jobject clazz, DisplayList* displayList) {
- return displayList->getPivotY();
-}
-
-#endif // USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// JNI Glue
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/view/GLES20DisplayList";
-
-static JNINativeMethod gMethods[] = {
-#ifdef USE_OPENGL_RENDERER
- { "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20DisplayList_destroyDisplayList },
- { "nGetDisplayListSize", "(I)I", (void*) android_view_GLES20DisplayList_getDisplayListSize },
- { "nSetDisplayListName", "(ILjava/lang/String;)V",
- (void*) android_view_GLES20DisplayList_setDisplayListName },
- { "nOutput", "(I)V", (void*) android_view_GLES20DisplayList_output },
-
- { "nReset", "(I)V", (void*) android_view_GLES20DisplayList_reset },
- { "nSetCaching", "(IZ)V", (void*) android_view_GLES20DisplayList_setCaching },
- { "nSetStaticMatrix", "(II)V", (void*) android_view_GLES20DisplayList_setStaticMatrix },
- { "nSetAnimationMatrix", "(II)V", (void*) android_view_GLES20DisplayList_setAnimationMatrix },
- { "nSetClipToBounds", "(IZ)V", (void*) android_view_GLES20DisplayList_setClipToBounds },
- { "nSetAlpha", "(IF)V", (void*) android_view_GLES20DisplayList_setAlpha },
- { "nSetHasOverlappingRendering", "(IZ)V",
- (void*) android_view_GLES20DisplayList_setHasOverlappingRendering },
- { "nSetTranslationX", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationX },
- { "nSetTranslationY", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationY },
- { "nSetTranslationZ", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationZ },
- { "nSetRotation", "(IF)V", (void*) android_view_GLES20DisplayList_setRotation },
- { "nSetRotationX", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationX },
- { "nSetRotationY", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationY },
- { "nSetScaleX", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleX },
- { "nSetScaleY", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleY },
- { "nSetTransformationInfo","(IFFFFFFFFF)V",
- (void*) android_view_GLES20DisplayList_setTransformationInfo },
- { "nSetPivotX", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotX },
- { "nSetPivotY", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotY },
- { "nSetCameraDistance", "(IF)V", (void*) android_view_GLES20DisplayList_setCameraDistance },
- { "nSetLeft", "(II)V", (void*) android_view_GLES20DisplayList_setLeft },
- { "nSetTop", "(II)V", (void*) android_view_GLES20DisplayList_setTop },
- { "nSetRight", "(II)V", (void*) android_view_GLES20DisplayList_setRight },
- { "nSetBottom", "(II)V", (void*) android_view_GLES20DisplayList_setBottom },
- { "nSetLeftTopRightBottom","(IIIII)V",
- (void*) android_view_GLES20DisplayList_setLeftTopRightBottom },
- { "nOffsetLeftAndRight", "(IF)V", (void*) android_view_GLES20DisplayList_offsetLeftAndRight },
- { "nOffsetTopAndBottom", "(IF)V", (void*) android_view_GLES20DisplayList_offsetTopAndBottom },
-
-
- { "nGetMatrix", "(II)V", (void*) android_view_GLES20DisplayList_getMatrix },
- { "nHasOverlappingRendering", "(I)Z", (void*) android_view_GLES20DisplayList_hasOverlappingRendering },
- { "nGetAlpha", "(I)F", (void*) android_view_GLES20DisplayList_getAlpha },
- { "nGetLeft", "(I)F", (void*) android_view_GLES20DisplayList_getLeft },
- { "nGetTop", "(I)F", (void*) android_view_GLES20DisplayList_getTop },
- { "nGetRight", "(I)F", (void*) android_view_GLES20DisplayList_getRight },
- { "nGetBottom", "(I)F", (void*) android_view_GLES20DisplayList_getBottom },
- { "nGetCameraDistance", "(I)F", (void*) android_view_GLES20DisplayList_getCameraDistance },
- { "nGetScaleX", "(I)F", (void*) android_view_GLES20DisplayList_getScaleX },
- { "nGetScaleY", "(I)F", (void*) android_view_GLES20DisplayList_getScaleY },
- { "nGetTranslationX", "(I)F", (void*) android_view_GLES20DisplayList_getTranslationX },
- { "nGetTranslationY", "(I)F", (void*) android_view_GLES20DisplayList_getTranslationY },
- { "nGetRotation", "(I)F", (void*) android_view_GLES20DisplayList_getRotation },
- { "nGetRotationX", "(I)F", (void*) android_view_GLES20DisplayList_getRotationX },
- { "nGetRotationY", "(I)F", (void*) android_view_GLES20DisplayList_getRotationY },
- { "nGetPivotX", "(I)F", (void*) android_view_GLES20DisplayList_getPivotX },
- { "nGetPivotY", "(I)F", (void*) android_view_GLES20DisplayList_getPivotY },
-#endif
-};
-
-#ifdef USE_OPENGL_RENDERER
- #define FIND_CLASS(var, className) \
- var = env->FindClass(className); \
- LOG_FATAL_IF(! var, "Unable to find class " className);
-
- #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
- var = env->GetMethodID(clazz, methodName, methodDescriptor); \
- LOG_FATAL_IF(! var, "Unable to find method " methodName);
-#else
- #define FIND_CLASS(var, className)
- #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
-#endif
-
-int register_android_view_GLES20DisplayList(JNIEnv* env) {
- return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
-
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 20eb356..9db35fc 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -98,7 +98,7 @@
private static SimpleDateFormat sFormatter;
static {
- System.loadLibrary("exif_jni");
+ System.loadLibrary("jhead_jni");
sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
}
diff --git a/preloaded-classes b/preloaded-classes
index 342126d..42412c6 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -977,14 +977,13 @@
android.view.DisplayInfo
android.view.DisplayInfo$1
android.view.DisplayList
+android.view.DisplayList$DisplayListFinalizer
android.view.FallbackEventHandler
android.view.FocusFinder
android.view.FocusFinder$1
android.view.FocusFinder$SequentialFocusComparator
android.view.GLES20Canvas
android.view.GLES20Canvas$CanvasFinalizer
-android.view.GLES20DisplayList
-android.view.GLES20DisplayList$DisplayListFinalizer
android.view.GLES20Layer
android.view.GLES20Layer$Finalizer
android.view.GLES20RecordingCanvas
diff --git a/services/Android.mk b/services/Android.mk
index 6ee7fca..8bd7629 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -7,7 +7,7 @@
LOCAL_SRC_FILES :=
# TODO: Move this to the product makefiles
-REQUIRED_SERVICES := core appwidget backup devicepolicy accessibility print
+REQUIRED_SERVICES := core accessibility appwidget backup devicepolicy print
include $(patsubst %,$(LOCAL_PATH)/%/java/service.mk,$(REQUIRED_SERVICES))
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index 6fd8871..3378e3d 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -38,6 +38,7 @@
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -46,21 +47,19 @@
/**
- * Redirects calls to this service to the instance of the service for the appropriate user.
+ * SystemService that publishes an IAppWidgetService.
*/
-public class AppWidgetService extends IAppWidgetService.Stub
-{
- private static final String TAG = "AppWidgetService";
+public class AppWidgetService extends SystemService {
+
+ static final String TAG = "AppWidgetService";
Context mContext;
- Locale mLocale;
- PackageManager mPackageManager;
- boolean mSafeMode;
- private final Handler mSaveStateHandler;
+ Handler mSaveStateHandler;
- private final SparseArray<AppWidgetServiceImpl> mAppWidgetServices;
+ SparseArray<AppWidgetServiceImpl> mAppWidgetServices;
- public AppWidgetService(Context context) {
+ @Override
+ public void onCreate(Context context) {
mContext = context;
mSaveStateHandler = BackgroundThread.getHandler();
@@ -70,294 +69,316 @@
mAppWidgetServices.append(0, primary);
}
- public void systemRunning(boolean safeMode) {
- mSafeMode = safeMode;
-
- mAppWidgetServices.get(0).systemReady(safeMode);
-
- // Register for the boot completed broadcast, so we can send the
- // ENABLE broacasts. If we try to send them now, they time out,
- // because the system isn't ready to handle them yet.
- mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
-
- // Register for configuration changes so we can update the names
- // of the widgets when the locale changes.
- mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED), null, null);
-
- // Register for broadcasts about package install, etc., so we can
- // update the provider list.
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addDataScheme("package");
- mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- filter, null, null);
- // Register for events related to sdcard installation.
- IntentFilter sdFilter = new IntentFilter();
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
- sdFilter, null, null);
-
- IntentFilter userFilter = new IntentFilter();
- userFilter.addAction(Intent.ACTION_USER_REMOVED);
- userFilter.addAction(Intent.ACTION_USER_STOPPING);
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
- onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL));
- } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) {
- onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL));
- }
- }
- }, userFilter);
+ @Override
+ public void onStart() {
+ publishBinderService(Context.APPWIDGET_SERVICE, mServiceImpl);
}
@Override
- public int allocateAppWidgetId(String packageName, int hostId, int userId)
- throws RemoteException {
- return getImplForUser(userId).allocateAppWidgetId(packageName, hostId);
- }
-
- @Override
- public int[] getAppWidgetIdsForHost(int hostId, int userId) throws RemoteException {
- return getImplForUser(userId).getAppWidgetIdsForHost(hostId);
- }
-
- @Override
- public void deleteAppWidgetId(int appWidgetId, int userId) throws RemoteException {
- getImplForUser(userId).deleteAppWidgetId(appWidgetId);
- }
-
- @Override
- public void deleteHost(int hostId, int userId) throws RemoteException {
- getImplForUser(userId).deleteHost(hostId);
- }
-
- @Override
- public void deleteAllHosts(int userId) throws RemoteException {
- getImplForUser(userId).deleteAllHosts();
- }
-
- @Override
- public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options, int userId)
- throws RemoteException {
- getImplForUser(userId).bindAppWidgetId(appWidgetId, provider, options);
- }
-
- @Override
- public boolean bindAppWidgetIdIfAllowed(
- String packageName, int appWidgetId, ComponentName provider, Bundle options, int userId)
- throws RemoteException {
- return getImplForUser(userId).bindAppWidgetIdIfAllowed(
- packageName, appWidgetId, provider, options);
- }
-
- @Override
- public boolean hasBindAppWidgetPermission(String packageName, int userId)
- throws RemoteException {
- return getImplForUser(userId).hasBindAppWidgetPermission(packageName);
- }
-
- @Override
- public void setBindAppWidgetPermission(String packageName, boolean permission, int userId)
- throws RemoteException {
- getImplForUser(userId).setBindAppWidgetPermission(packageName, permission);
- }
-
- @Override
- public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
- int userId) throws RemoteException {
- getImplForUser(userId).bindRemoteViewsService(appWidgetId, intent, connection);
- }
-
- @Override
- public int[] startListening(IAppWidgetHost host, String packageName, int hostId,
- List<RemoteViews> updatedViews, int userId) throws RemoteException {
- return getImplForUser(userId).startListening(host, packageName, hostId, updatedViews);
- }
-
- public void onUserRemoved(int userId) {
- if (userId < 1) return;
- synchronized (mAppWidgetServices) {
- AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
- mAppWidgetServices.remove(userId);
-
- if (impl == null) {
- AppWidgetServiceImpl.getSettingsFile(userId).delete();
- } else {
- impl.onUserRemoved();
- }
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+ mServiceImpl.systemRunning(isSafeMode());
}
}
- public void onUserStopping(int userId) {
- if (userId < 1) return;
- synchronized (mAppWidgetServices) {
- AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
- if (impl != null) {
+ private final AppWidgetServiceStub mServiceImpl = new AppWidgetServiceStub();
+
+ private class AppWidgetServiceStub extends IAppWidgetService.Stub {
+
+ private boolean mSafeMode;
+ private Locale mLocale;
+ private PackageManager mPackageManager;
+
+ public void systemRunning(boolean safeMode) {
+ mSafeMode = safeMode;
+
+ mAppWidgetServices.get(0).systemReady(safeMode);
+
+ // Register for the boot completed broadcast, so we can send the
+ // ENABLE broacasts. If we try to send them now, they time out,
+ // because the system isn't ready to handle them yet.
+ mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+ new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
+
+ // Register for configuration changes so we can update the names
+ // of the widgets when the locale changes.
+ mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+ new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED), null, null);
+
+ // Register for broadcasts about package install, etc., so we can
+ // update the provider list.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addDataScheme("package");
+ mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+ filter, null, null);
+ // Register for events related to sdcard installation.
+ IntentFilter sdFilter = new IntentFilter();
+ sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+ sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+ mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+ sdFilter, null, null);
+
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ userFilter.addAction(Intent.ACTION_USER_STOPPING);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL));
+ } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) {
+ onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+ UserHandle.USER_NULL));
+ }
+ }
+ }, userFilter);
+ }
+
+ @Override
+ public int allocateAppWidgetId(String packageName, int hostId, int userId)
+ throws RemoteException {
+ return getImplForUser(userId).allocateAppWidgetId(packageName, hostId);
+ }
+
+ @Override
+ public int[] getAppWidgetIdsForHost(int hostId, int userId) throws RemoteException {
+ return getImplForUser(userId).getAppWidgetIdsForHost(hostId);
+ }
+
+ @Override
+ public void deleteAppWidgetId(int appWidgetId, int userId) throws RemoteException {
+ getImplForUser(userId).deleteAppWidgetId(appWidgetId);
+ }
+
+ @Override
+ public void deleteHost(int hostId, int userId) throws RemoteException {
+ getImplForUser(userId).deleteHost(hostId);
+ }
+
+ @Override
+ public void deleteAllHosts(int userId) throws RemoteException {
+ getImplForUser(userId).deleteAllHosts();
+ }
+
+ @Override
+ public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options,
+ int userId) throws RemoteException {
+ getImplForUser(userId).bindAppWidgetId(appWidgetId, provider, options);
+ }
+
+ @Override
+ public boolean bindAppWidgetIdIfAllowed(
+ String packageName, int appWidgetId, ComponentName provider, Bundle options,
+ int userId) throws RemoteException {
+ return getImplForUser(userId).bindAppWidgetIdIfAllowed(
+ packageName, appWidgetId, provider, options);
+ }
+
+ @Override
+ public boolean hasBindAppWidgetPermission(String packageName, int userId)
+ throws RemoteException {
+ return getImplForUser(userId).hasBindAppWidgetPermission(packageName);
+ }
+
+ @Override
+ public void setBindAppWidgetPermission(String packageName, boolean permission, int userId)
+ throws RemoteException {
+ getImplForUser(userId).setBindAppWidgetPermission(packageName, permission);
+ }
+
+ @Override
+ public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
+ int userId) throws RemoteException {
+ getImplForUser(userId).bindRemoteViewsService(appWidgetId, intent, connection);
+ }
+
+ @Override
+ public int[] startListening(IAppWidgetHost host, String packageName, int hostId,
+ List<RemoteViews> updatedViews, int userId) throws RemoteException {
+ return getImplForUser(userId).startListening(host, packageName, hostId, updatedViews);
+ }
+
+ public void onUserRemoved(int userId) {
+ if (userId < 1) return;
+ synchronized (mAppWidgetServices) {
+ AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
mAppWidgetServices.remove(userId);
- impl.onUserStopping();
- }
- }
- }
- private void checkPermission(int userId) {
- int realUserId = ActivityManager.handleIncomingUser(
- Binder.getCallingPid(),
- Binder.getCallingUid(),
- userId,
- false, /* allowAll */
- true, /* requireFull */
- this.getClass().getSimpleName(),
- this.getClass().getPackage().getName());
- }
-
- private AppWidgetServiceImpl getImplForUser(int userId) {
- checkPermission(userId);
- boolean sendInitial = false;
- AppWidgetServiceImpl service;
- synchronized (mAppWidgetServices) {
- service = mAppWidgetServices.get(userId);
- if (service == null) {
- Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId + ", adding");
- // TODO: Verify that it's a valid user
- service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler);
- service.systemReady(mSafeMode);
- // Assume that BOOT_COMPLETED was received, as this is a non-primary user.
- mAppWidgetServices.append(userId, service);
- sendInitial = true;
- }
- }
- if (sendInitial) {
- service.sendInitialBroadcasts();
- }
- return service;
- }
-
- @Override
- public int[] getAppWidgetIds(ComponentName provider, int userId) throws RemoteException {
- return getImplForUser(userId).getAppWidgetIds(provider);
- }
-
- @Override
- public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId)
- throws RemoteException {
- return getImplForUser(userId).getAppWidgetInfo(appWidgetId);
- }
-
- @Override
- public RemoteViews getAppWidgetViews(int appWidgetId, int userId) throws RemoteException {
- return getImplForUser(userId).getAppWidgetViews(appWidgetId);
- }
-
- @Override
- public void updateAppWidgetOptions(int appWidgetId, Bundle options, int userId) {
- getImplForUser(userId).updateAppWidgetOptions(appWidgetId, options);
- }
-
- @Override
- public Bundle getAppWidgetOptions(int appWidgetId, int userId) {
- return getImplForUser(userId).getAppWidgetOptions(appWidgetId);
- }
-
- @Override
- public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId)
- throws RemoteException {
- return getImplForUser(userId).getInstalledProviders(categoryFilter);
- }
-
- @Override
- public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId, int userId)
- throws RemoteException {
- getImplForUser(userId).notifyAppWidgetViewDataChanged(
- appWidgetIds, viewId);
- }
-
- @Override
- public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId)
- throws RemoteException {
- getImplForUser(userId).partiallyUpdateAppWidgetIds(
- appWidgetIds, views);
- }
-
- @Override
- public void stopListening(int hostId, int userId) throws RemoteException {
- getImplForUser(userId).stopListening(hostId);
- }
-
- @Override
- public void unbindRemoteViewsService(int appWidgetId, Intent intent, int userId)
- throws RemoteException {
- getImplForUser(userId).unbindRemoteViewsService(
- appWidgetId, intent);
- }
-
- @Override
- public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId)
- throws RemoteException {
- getImplForUser(userId).updateAppWidgetIds(appWidgetIds, views);
- }
-
- @Override
- public void updateAppWidgetProvider(ComponentName provider, RemoteViews views, int userId)
- throws RemoteException {
- getImplForUser(userId).updateAppWidgetProvider(provider, views);
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
- // Dump the state of all the app widget providers
- synchronized (mAppWidgetServices) {
- IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
- for (int i = 0; i < mAppWidgetServices.size(); i++) {
- pw.println("User: " + mAppWidgetServices.keyAt(i));
- ipw.increaseIndent();
- AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
- service.dump(fd, ipw, args);
- ipw.decreaseIndent();
- }
- }
- }
-
- BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- // Slog.d(TAG, "received " + action);
- if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
- if (userId >= 0) {
- getImplForUser(userId).sendInitialBroadcasts();
+ if (impl == null) {
+ AppWidgetServiceImpl.getSettingsFile(userId).delete();
} else {
- Slog.w(TAG, "Incorrect user handle supplied in " + intent);
+ impl.onUserRemoved();
}
- } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+ }
+ }
+
+ public void onUserStopping(int userId) {
+ if (userId < 1) return;
+ synchronized (mAppWidgetServices) {
+ AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
+ if (impl != null) {
+ mAppWidgetServices.remove(userId);
+ impl.onUserStopping();
+ }
+ }
+ }
+
+ private void checkPermission(int userId) {
+ int realUserId = ActivityManager.handleIncomingUser(
+ Binder.getCallingPid(),
+ Binder.getCallingUid(),
+ userId,
+ false, /* allowAll */
+ true, /* requireFull */
+ this.getClass().getSimpleName(),
+ this.getClass().getPackage().getName());
+ }
+
+ private AppWidgetServiceImpl getImplForUser(int userId) {
+ checkPermission(userId);
+ boolean sendInitial = false;
+ AppWidgetServiceImpl service;
+ synchronized (mAppWidgetServices) {
+ service = mAppWidgetServices.get(userId);
+ if (service == null) {
+ Slog.i(TAG, "Unable to find AppWidgetServiceImpl for user " + userId
+ + ", adding");
+ // TODO: Verify that it's a valid user
+ service = new AppWidgetServiceImpl(mContext, userId, mSaveStateHandler);
+ service.systemReady(mSafeMode);
+ // Assume that BOOT_COMPLETED was received, as this is a non-primary user.
+ mAppWidgetServices.append(userId, service);
+ sendInitial = true;
+ }
+ }
+ if (sendInitial) {
+ service.sendInitialBroadcasts();
+ }
+ return service;
+ }
+
+ @Override
+ public int[] getAppWidgetIds(ComponentName provider, int userId) throws RemoteException {
+ return getImplForUser(userId).getAppWidgetIds(provider);
+ }
+
+ @Override
+ public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId, int userId)
+ throws RemoteException {
+ return getImplForUser(userId).getAppWidgetInfo(appWidgetId);
+ }
+
+ @Override
+ public RemoteViews getAppWidgetViews(int appWidgetId, int userId) throws RemoteException {
+ return getImplForUser(userId).getAppWidgetViews(appWidgetId);
+ }
+
+ @Override
+ public void updateAppWidgetOptions(int appWidgetId, Bundle options, int userId) {
+ getImplForUser(userId).updateAppWidgetOptions(appWidgetId, options);
+ }
+
+ @Override
+ public Bundle getAppWidgetOptions(int appWidgetId, int userId) {
+ return getImplForUser(userId).getAppWidgetOptions(appWidgetId);
+ }
+
+ @Override
+ public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter, int userId)
+ throws RemoteException {
+ return getImplForUser(userId).getInstalledProviders(categoryFilter);
+ }
+
+ @Override
+ public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId, int userId)
+ throws RemoteException {
+ getImplForUser(userId).notifyAppWidgetViewDataChanged(
+ appWidgetIds, viewId);
+ }
+
+ @Override
+ public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId)
+ throws RemoteException {
+ getImplForUser(userId).partiallyUpdateAppWidgetIds(
+ appWidgetIds, views);
+ }
+
+ @Override
+ public void stopListening(int hostId, int userId) throws RemoteException {
+ getImplForUser(userId).stopListening(hostId);
+ }
+
+ @Override
+ public void unbindRemoteViewsService(int appWidgetId, Intent intent, int userId)
+ throws RemoteException {
+ getImplForUser(userId).unbindRemoteViewsService(
+ appWidgetId, intent);
+ }
+
+ @Override
+ public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views, int userId)
+ throws RemoteException {
+ getImplForUser(userId).updateAppWidgetIds(appWidgetIds, views);
+ }
+
+ @Override
+ public void updateAppWidgetProvider(ComponentName provider, RemoteViews views, int userId)
+ throws RemoteException {
+ getImplForUser(userId).updateAppWidgetProvider(provider, views);
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
+ // Dump the state of all the app widget providers
+ synchronized (mAppWidgetServices) {
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
for (int i = 0; i < mAppWidgetServices.size(); i++) {
+ pw.println("User: " + mAppWidgetServices.keyAt(i));
+ ipw.increaseIndent();
AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
- service.onConfigurationChanged();
+ service.dump(fd, ipw, args);
+ ipw.decreaseIndent();
}
- } else {
- int sendingUser = getSendingUserId();
- if (sendingUser == UserHandle.USER_ALL) {
+ }
+ }
+
+ BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ // Slog.d(TAG, "received " + action);
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId >= 0) {
+ getImplForUser(userId).sendInitialBroadcasts();
+ } else {
+ Slog.w(TAG, "Incorrect user handle supplied in " + intent);
+ }
+ } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
for (int i = 0; i < mAppWidgetServices.size(); i++) {
AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
- service.onBroadcastReceived(intent);
+ service.onConfigurationChanged();
}
} else {
- AppWidgetServiceImpl service = mAppWidgetServices.get(sendingUser);
- if (service != null) {
- service.onBroadcastReceived(intent);
+ int sendingUser = getSendingUserId();
+ if (sendingUser == UserHandle.USER_ALL) {
+ for (int i = 0; i < mAppWidgetServices.size(); i++) {
+ AppWidgetServiceImpl service = mAppWidgetServices.valueAt(i);
+ service.onBroadcastReceived(intent);
+ }
+ } else {
+ AppWidgetServiceImpl service = mAppWidgetServices.get(sendingUser);
+ if (service != null) {
+ service.onBroadcastReceived(intent);
+ }
}
}
}
- }
- };
+ };
+ }
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 18c8ec4..9277cce2 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -83,6 +83,7 @@
import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.IObbBackupService;
import com.android.server.EventLogTags;
+import com.android.server.SystemService;
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
import java.io.BufferedInputStream;
@@ -136,6 +137,7 @@
import javax.crypto.spec.SecretKeySpec;
public class BackupManagerService extends IBackupManager.Stub {
+
private static final String TAG = "BackupManagerService";
private static final boolean DEBUG = true;
private static final boolean MORE_DEBUG = false;
@@ -6089,7 +6091,7 @@
}
}
- // clean up the BackupManagerService side of the bookkeeping
+ // clean up the BackupManagerImpl side of the bookkeeping
// and cancel any pending timeout message
mBackupManager.clearRestoreSession(mSession);
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerSystemService.java b/services/backup/java/com/android/server/backup/BackupManagerSystemService.java
new file mode 100644
index 0000000..db2c94a
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/BackupManagerSystemService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup;
+
+import android.content.Context;
+
+import com.android.server.SystemService;
+
+public class BackupManagerSystemService extends SystemService {
+ private BackupManagerService mBackupManagerImpl;
+
+ @Override
+ public void onCreate(Context context) {
+ mBackupManagerImpl = new BackupManagerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.BACKUP_SERVICE, mBackupManagerImpl);
+ }
+}
+
diff --git a/services/core/java/com/android/server/SystemServer.java b/services/core/java/com/android/server/SystemServer.java
index 38f4c78d..10adc46 100644
--- a/services/core/java/com/android/server/SystemServer.java
+++ b/services/core/java/com/android/server/SystemServer.java
@@ -31,6 +31,7 @@
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -52,11 +53,8 @@
import com.android.server.accounts.AccountManagerService;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.BatteryStatsService;
-import com.android.server.appwidget.AppWidgetService;
-import com.android.server.backup.BackupManagerService;
import com.android.server.clipboard.ClipboardService;
import com.android.server.content.ContentService;
-import com.android.server.devicepolicy.DevicePolicyManagerService;
import com.android.server.display.DisplayManagerService;
import com.android.server.dreams.DreamManagerService;
import com.android.server.input.InputManagerService;
@@ -72,7 +70,6 @@
import com.android.server.pm.UserManagerService;
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
-import com.android.server.print.PrintManagerService;
import com.android.server.search.SearchManagerService;
import com.android.server.statusbar.StatusBarManagerService;
import com.android.server.storage.DeviceStorageMonitorService;
@@ -98,6 +95,19 @@
ContentResolver mContentResolver;
+ /*
+ * Implementation class names. TODO: Move them to a codegen class or load
+ * them from the build system somehow.
+ */
+ private static final String BACKUP_MANAGER_SERVICE_CLASS =
+ "com.android.server.backup.BackupManagerSystemService";
+ private static final String DEVICE_POLICY_MANAGER_SERVICE_CLASS =
+ "com.android.server.devicepolicy.DevicePolicyManagerSystemService";
+ private static final String APPWIDGET_SERVICE_CLASS =
+ "com.android.server.appwidget.AppWidgetService";
+ private static final String PRINT_MANAGER_SERVICE_CLASS =
+ "com.android.server.print.PrintManagerService";
+
void reportWtf(String msg, Throwable e) {
Slog.w(TAG, "***********************************************");
Log.wtf(TAG, "BOOT FAILURE " + msg, e);
@@ -357,11 +367,9 @@
Slog.e("System", "************ Failure starting core service", e);
}
- DevicePolicyManagerService devicePolicy = null;
StatusBarManagerService statusBar = null;
INotificationManager notification = null;
InputMethodManagerService imm = null;
- AppWidgetService appWidget = null;
WallpaperManagerService wallpaper = null;
LocationManagerService location = null;
CountryDetectorService countryDetector = null;
@@ -369,7 +377,6 @@
LockSettingsService lockSettings = null;
DreamManagerService dreamy = null;
AssetAtlasService atlas = null;
- PrintManagerService printManager = null;
MediaRouterService mediaRouter = null;
// Bring up services needed for UI.
@@ -441,8 +448,7 @@
try {
Slog.i(TAG, "Device Policy");
- devicePolicy = new DevicePolicyManagerService(context);
- ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
+ systemServiceManager.startService(DEVICE_POLICY_MANAGER_SERVICE_CLASS);
} catch (Throwable e) {
reportWtf("starting DevicePolicyService", e);
}
@@ -692,16 +698,14 @@
if (!disableNonCoreServices) {
try {
Slog.i(TAG, "Backup Service");
- ServiceManager.addService(Context.BACKUP_SERVICE,
- new BackupManagerService(context));
+ systemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Backup Service", e);
}
try {
Slog.i(TAG, "AppWidget Service");
- appWidget = new AppWidgetService(context);
- ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
+ systemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
} catch (Throwable e) {
reportWtf("starting AppWidget Service", e);
}
@@ -792,8 +796,7 @@
try {
Slog.i(TAG, "Print Service");
- printManager = new PrintManagerService(context);
- ServiceManager.addService(Context.PRINT_SERVICE, printManager);
+ systemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
} catch (Throwable e) {
reportWtf("starting Print Service", e);
}
@@ -839,13 +842,8 @@
}
}
- if (devicePolicy != null) {
- try {
- devicePolicy.systemReady();
- } catch (Throwable e) {
- reportWtf("making Device Policy Service ready", e);
- }
- }
+ // Needed by DevicePolicyManager for initialization
+ systemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
systemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
@@ -896,7 +894,6 @@
final ConnectivityService connectivityF = connectivity;
final DockObserver dockF = dock;
final UsbService usbF = usb;
- final AppWidgetService appWidgetF = appWidget;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
final RecognitionManagerService recognitionF = recognition;
@@ -910,7 +907,6 @@
final AssetAtlasService atlasF = atlas;
final InputManagerService inputManagerF = inputManager;
final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
- final PrintManagerService printManagerF = printManager;
final MediaRouterService mediaRouterF = mediaRouter;
// We now tell the activity manager it is okay to run third party
@@ -984,11 +980,6 @@
systemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
try {
- if (appWidgetF != null) appWidgetF.systemRunning(safeMode);
- } catch (Throwable e) {
- reportWtf("Notifying AppWidgetService running", e);
- }
- try {
if (wallpaperF != null) wallpaperF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying WallpaperService running", e);
@@ -1048,12 +1039,6 @@
}
try {
- if (printManagerF != null) printManagerF.systemRuning();
- } catch (Throwable e) {
- reportWtf("Notifying PrintManagerService running", e);
- }
-
- try {
if (mediaRouterF != null) mediaRouterF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying MediaRouterService running", e);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java
new file mode 100644
index 0000000..160aa39
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerSystemService.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.content.Context;
+
+import com.android.server.SystemService;
+
+/**
+ * SystemService wrapper for the DevicePolicyManager implementation. Publishes
+ * Context.DEVICE_POLICY_SERVICE.
+ */
+public final class DevicePolicyManagerSystemService extends SystemService {
+ private DevicePolicyManagerService mDevicePolicyManagerImpl;
+
+ @Override
+ public void onCreate(Context context) {
+ mDevicePolicyManagerImpl = new DevicePolicyManagerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManagerImpl);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_LOCK_SETTINGS_READY) {
+ mDevicePolicyManagerImpl.systemReady();
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index e24fdb5..7f146a7 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -51,6 +51,8 @@
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.server.SystemService;
+import com.android.server.devicepolicy.DevicePolicyManagerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -58,604 +60,633 @@
import java.util.List;
import java.util.Set;
-public final class PrintManagerService extends IPrintManager.Stub {
+/**
+ * SystemService wrapper for the PrintManager implementation. Publishes
+ * Context.PRINT_SERVICE.
+ * PrintManager implementation is contained within.
+ */
- private static final char COMPONENT_NAME_SEPARATOR = ':';
+public final class PrintManagerService extends SystemService {
- private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME =
- "EXTRA_PRINT_SERVICE_COMPONENT_NAME";
+ private PrintManagerImpl mPrintManagerImpl;
- private final Object mLock = new Object();
-
- private final Context mContext;
-
- private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
-
- private int mCurrentUserId = UserHandle.USER_OWNER;
-
- public PrintManagerService(Context context) {
- mContext = context;
- registerContentObservers();
- registerBoradcastReceivers();
+ @Override
+ public void onCreate(Context context) {
+ mPrintManagerImpl = new PrintManagerImpl(context);
+ }
+ @Override
+ public void onStart() {
+ publishBinderService(Context.PRINT_SERVICE, mPrintManagerImpl);
}
- public void systemRuning() {
- BackgroundThread.getHandler().post(new Runnable() {
- @Override
- public void run() {
- final UserState userState;
- synchronized (mLock) {
- userState = getCurrentUserStateLocked();
- userState.updateIfNeededLocked();
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+ mPrintManagerImpl.systemRunning();
+ }
+ }
+
+ class PrintManagerImpl extends IPrintManager.Stub {
+ private static final char COMPONENT_NAME_SEPARATOR = ':';
+
+ private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME =
+ "EXTRA_PRINT_SERVICE_COMPONENT_NAME";
+
+ private final Object mLock = new Object();
+
+ private final Context mContext;
+
+ private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
+
+ private int mCurrentUserId = UserHandle.USER_OWNER;
+
+ PrintManagerImpl(Context context) {
+ mContext = context;
+ registerContentObservers();
+ registerBoradcastReceivers();
+ }
+
+ public void systemRunning() {
+ BackgroundThread.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getCurrentUserStateLocked();
+ userState.updateIfNeededLocked();
+ }
+ // This is the first time we switch to this user after boot, so
+ // now is the time to remove obsolete print jobs since they
+ // are from the last boot and no application would query them.
+ userState.removeObsoletePrintJobs();
}
- // This is the first time we switch to this user after boot, so
- // now is the time to remove obsolete print jobs since they
- // are from the last boot and no application would query them.
- userState.removeObsoletePrintJobs();
+ });
+ }
+
+ @Override
+ public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
+ PrintAttributes attributes, String packageName, int appId, int userId) {
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ String resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
}
- });
- }
-
- @Override
- public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
- PrintAttributes attributes, String packageName, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- String resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- return userState.print(printJobName, adapter, attributes,
- resolvedPackageName, resolvedAppId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- return userState.getPrintJobInfos(resolvedAppId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- return userState.getPrintJobInfo(printJobId, resolvedAppId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.cancelPrintJob(printJobId, resolvedAppId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.restartPrintJob(printJobId, resolvedAppId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public List<PrintServiceInfo> getEnabledPrintServices(int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- return userState.getEnabledPrintServices();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public List<PrintServiceInfo> getInstalledPrintServices(int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- return userState.getInstalledPrintServices();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
- int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.createPrinterDiscoverySession(observer);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
- int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.destroyPrinterDiscoverySession(observer);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
- List<PrinterId> priorityList, int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.startPrinterDiscovery(observer, priorityList);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.stopPrinterDiscovery(observer);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void validatePrinters(List<PrinterId> printerIds, int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.validatePrinters(printerIds);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void startPrinterStateTracking(PrinterId printerId, int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.startPrinterStateTracking(printerId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void stopPrinterStateTracking(PrinterId printerId, int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.stopPrinterStateTracking(printerId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
- int appId, int userId) throws RemoteException {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.addPrintJobStateChangeListener(listener, resolvedAppId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener,
- int userId) {
- final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final UserState userState;
- synchronized (mLock) {
- userState = getOrCreateUserStateLocked(resolvedUserId);
- }
- final long identity = Binder.clearCallingIdentity();
- try {
- userState.removePrintJobStateChangeListener(listener);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump PrintManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
- synchronized (mLock) {
final long identity = Binder.clearCallingIdentity();
try {
- pw.println("PRINT MANAGER STATE (dumpsys print)");
- final int userStateCount = mUserStates.size();
- for (int i = 0; i < userStateCount; i++) {
- UserState userState = mUserStates.valueAt(i);
- userState.dump(fd, pw, "");
- pw.println();
- }
+ return userState.print(printJobName, adapter, attributes,
+ resolvedPackageName, resolvedAppId);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- }
- private void registerContentObservers() {
- final Uri enabledPrintServicesUri = Settings.Secure.getUriFor(
- Settings.Secure.ENABLED_PRINT_SERVICES);
-
- ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (enabledPrintServicesUri.equals(uri)) {
- synchronized (mLock) {
- UserState userState = getCurrentUserStateLocked();
- userState.updateIfNeededLocked();
- }
- }
+ @Override
+ public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) {
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
}
- };
-
- mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri,
- false, observer, UserHandle.USER_ALL);
- }
-
- private void registerBoradcastReceivers() {
- PackageMonitor monitor = new PackageMonitor() {
- @Override
- public void onPackageModified(String packageName) {
- synchronized (mLock) {
- boolean servicesChanged = false;
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
- Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
- while (iterator.hasNext()) {
- ComponentName componentName = iterator.next();
- if (packageName.equals(componentName.getPackageName())) {
- servicesChanged = true;
- }
- }
- if (servicesChanged) {
- userState.updateIfNeededLocked();
- }
- }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return userState.getPrintJobInfos(resolvedAppId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
-
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- synchronized (mLock) {
- boolean servicesRemoved = false;
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
- Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
- while (iterator.hasNext()) {
- ComponentName componentName = iterator.next();
- if (packageName.equals(componentName.getPackageName())) {
- iterator.remove();
- servicesRemoved = true;
- }
- }
- if (servicesRemoved) {
- persistComponentNamesToSettingLocked(
- Settings.Secure.ENABLED_PRINT_SERVICES,
- userState.getEnabledServices(), getChangingUserId());
- userState.updateIfNeededLocked();
- }
- }
- }
-
- @Override
- public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
- int uid, boolean doit) {
- synchronized (mLock) {
- UserState userState = getOrCreateUserStateLocked(getChangingUserId());
- boolean stoppedSomePackages = false;
- Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
- while (iterator.hasNext()) {
- ComponentName componentName = iterator.next();
- String componentPackage = componentName.getPackageName();
- for (String stoppedPackage : stoppedPackages) {
- if (componentPackage.equals(stoppedPackage)) {
- if (!doit) {
- return true;
- }
- stoppedSomePackages = true;
- break;
- }
- }
- }
- if (stoppedSomePackages) {
- userState.updateIfNeededLocked();
- }
- return false;
- }
- }
-
- @Override
- public void onPackageAdded(String packageName, int uid) {
- Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE);
- intent.setPackage(packageName);
-
- List<ResolveInfo> installedServices = mContext.getPackageManager()
- .queryIntentServicesAsUser(intent, PackageManager.GET_SERVICES,
- getChangingUserId());
-
- if (installedServices == null) {
- return;
- }
-
- final int installedServiceCount = installedServices.size();
- for (int i = 0; i < installedServiceCount; i++) {
- ServiceInfo serviceInfo = installedServices.get(i).serviceInfo;
- ComponentName component = new ComponentName(serviceInfo.packageName,
- serviceInfo.name);
- String label = serviceInfo.loadLabel(mContext.getPackageManager()).toString();
- showEnableInstalledPrintServiceNotification(component, label,
- getChangingUserId());
- }
- }
-
- private void persistComponentNamesToSettingLocked(String settingName,
- Set<ComponentName> componentNames, int userId) {
- StringBuilder builder = new StringBuilder();
- for (ComponentName componentName : componentNames) {
- if (builder.length() > 0) {
- builder.append(COMPONENT_NAME_SEPARATOR);
- }
- builder.append(componentName.flattenToShortString());
- }
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- settingName, builder.toString(), userId);
- }
- };
-
- // package changes
- monitor.register(mContext, BackgroundThread.getHandler().getLooper(),
- UserHandle.ALL, true);
-
- // user changes
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
- intentFilter.addAction(Intent.ACTION_USER_REMOVED);
-
- mContext.registerReceiverAsUser(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
- } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
- removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
- }
- }
- }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler());
- }
-
- private UserState getCurrentUserStateLocked() {
- return getOrCreateUserStateLocked(mCurrentUserId);
- }
-
- private UserState getOrCreateUserStateLocked(int userId) {
- UserState userState = mUserStates.get(userId);
- if (userState == null) {
- userState = new UserState(mContext, userId, mLock);
- mUserStates.put(userId, userState);
}
- return userState;
- }
- private void switchUser(int newUserId) {
- UserState userState;
- synchronized (mLock) {
- if (newUserId == mCurrentUserId) {
+ @Override
+ public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return userState.getPrintJobInfo(printJobId, resolvedAppId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.cancelPrintJob(printJobId, resolvedAppId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.restartPrintJob(printJobId, resolvedAppId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public List<PrintServiceInfo> getEnabledPrintServices(int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return userState.getEnabledPrintServices();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public List<PrintServiceInfo> getInstalledPrintServices(int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return userState.getInstalledPrintServices();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
+ int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.createPrinterDiscoverySession(observer);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
+ int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.destroyPrinterDiscoverySession(observer);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
+ List<PrinterId> priorityList, int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.startPrinterDiscovery(observer, priorityList);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.stopPrinterDiscovery(observer);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void validatePrinters(List<PrinterId> printerIds, int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.validatePrinters(printerIds);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void startPrinterStateTracking(PrinterId printerId, int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.startPrinterStateTracking(printerId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void stopPrinterStateTracking(PrinterId printerId, int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.stopPrinterStateTracking(printerId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
+ int appId, int userId) throws RemoteException {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.addPrintJobStateChangeListener(listener, resolvedAppId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener,
+ int userId) {
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final UserState userState;
+ synchronized (mLock) {
+ userState = getOrCreateUserStateLocked(resolvedUserId);
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ userState.removePrintJobStateChangeListener(listener);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump PrintManager from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
return;
}
- mCurrentUserId = newUserId;
- userState = mUserStates.get(mCurrentUserId);
+
+ synchronized (mLock) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ pw.println("PRINT MANAGER STATE (dumpsys print)");
+ final int userStateCount = mUserStates.size();
+ for (int i = 0; i < userStateCount; i++) {
+ UserState userState = mUserStates.valueAt(i);
+ userState.dump(fd, pw, "");
+ pw.println();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+
+ private void registerContentObservers() {
+ final Uri enabledPrintServicesUri = Settings.Secure.getUriFor(
+ Settings.Secure.ENABLED_PRINT_SERVICES);
+ ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (enabledPrintServicesUri.equals(uri)) {
+ synchronized (mLock) {
+ UserState userState = getCurrentUserStateLocked();
+ userState.updateIfNeededLocked();
+ }
+ }
+ }
+ };
+
+ mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri,
+ false, observer, UserHandle.USER_ALL);
+ }
+
+ private void registerBoradcastReceivers() {
+ PackageMonitor monitor = new PackageMonitor() {
+ @Override
+ public void onPackageModified(String packageName) {
+ synchronized (mLock) {
+ boolean servicesChanged = false;
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
+ while (iterator.hasNext()) {
+ ComponentName componentName = iterator.next();
+ if (packageName.equals(componentName.getPackageName())) {
+ servicesChanged = true;
+ }
+ }
+ if (servicesChanged) {
+ userState.updateIfNeededLocked();
+ }
+ }
+ }
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ synchronized (mLock) {
+ boolean servicesRemoved = false;
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
+ while (iterator.hasNext()) {
+ ComponentName componentName = iterator.next();
+ if (packageName.equals(componentName.getPackageName())) {
+ iterator.remove();
+ servicesRemoved = true;
+ }
+ }
+ if (servicesRemoved) {
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.ENABLED_PRINT_SERVICES,
+ userState.getEnabledServices(), getChangingUserId());
+ userState.updateIfNeededLocked();
+ }
+ }
+ }
+
+ @Override
+ public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
+ int uid, boolean doit) {
+ synchronized (mLock) {
+ UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+ boolean stoppedSomePackages = false;
+ Iterator<ComponentName> iterator = userState.getEnabledServices()
+ .iterator();
+ while (iterator.hasNext()) {
+ ComponentName componentName = iterator.next();
+ String componentPackage = componentName.getPackageName();
+ for (String stoppedPackage : stoppedPackages) {
+ if (componentPackage.equals(stoppedPackage)) {
+ if (!doit) {
+ return true;
+ }
+ stoppedSomePackages = true;
+ break;
+ }
+ }
+ }
+ if (stoppedSomePackages) {
+ userState.updateIfNeededLocked();
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public void onPackageAdded(String packageName, int uid) {
+ Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE);
+ intent.setPackage(packageName);
+
+ List<ResolveInfo> installedServices = mContext.getPackageManager()
+ .queryIntentServicesAsUser(intent, PackageManager.GET_SERVICES,
+ getChangingUserId());
+
+ if (installedServices == null) {
+ return;
+ }
+
+ final int installedServiceCount = installedServices.size();
+ for (int i = 0; i < installedServiceCount; i++) {
+ ServiceInfo serviceInfo = installedServices.get(i).serviceInfo;
+ ComponentName component = new ComponentName(serviceInfo.packageName,
+ serviceInfo.name);
+ String label = serviceInfo.loadLabel(mContext.getPackageManager())
+ .toString();
+ showEnableInstalledPrintServiceNotification(component, label,
+ getChangingUserId());
+ }
+ }
+
+ private void persistComponentNamesToSettingLocked(String settingName,
+ Set<ComponentName> componentNames, int userId) {
+ StringBuilder builder = new StringBuilder();
+ for (ComponentName componentName : componentNames) {
+ if (builder.length() > 0) {
+ builder.append(COMPONENT_NAME_SEPARATOR);
+ }
+ builder.append(componentName.flattenToShortString());
+ }
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ settingName, builder.toString(), userId);
+ }
+ };
+
+ // package changes
+ monitor.register(mContext, BackgroundThread.getHandler().getLooper(),
+ UserHandle.ALL, true);
+
+ // user changes
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+ intentFilter.addAction(Intent.ACTION_USER_REMOVED);
+
+ mContext.registerReceiverAsUser(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+ } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+ }
+ }
+ }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler());
+ }
+
+ private UserState getCurrentUserStateLocked() {
+ return getOrCreateUserStateLocked(mCurrentUserId);
+ }
+
+ private UserState getOrCreateUserStateLocked(int userId) {
+ UserState userState = mUserStates.get(userId);
if (userState == null) {
- userState = getCurrentUserStateLocked();
- userState.updateIfNeededLocked();
- } else {
- userState.updateIfNeededLocked();
+ userState = new UserState(mContext, userId, mLock);
+ mUserStates.put(userId, userState);
+ }
+ return userState;
+ }
+
+ private void switchUser(int newUserId) {
+ UserState userState;
+ synchronized (mLock) {
+ if (newUserId == mCurrentUserId) {
+ return;
+ }
+ mCurrentUserId = newUserId;
+ userState = mUserStates.get(mCurrentUserId);
+ if (userState == null) {
+ userState = getCurrentUserStateLocked();
+ userState.updateIfNeededLocked();
+ } else {
+ userState.updateIfNeededLocked();
+ }
+ }
+ // This is the first time we switch to this user after boot, so
+ // now is the time to remove obsolete print jobs since they
+ // are from the last boot and no application would query them.
+ userState.removeObsoletePrintJobs();
+ }
+
+ private void removeUser(int removedUserId) {
+ synchronized (mLock) {
+ UserState userState = mUserStates.get(removedUserId);
+ if (userState != null) {
+ userState.destroyLocked();
+ mUserStates.remove(removedUserId);
+ }
}
}
- // This is the first time we switch to this user after boot, so
- // now is the time to remove obsolete print jobs since they
- // are from the last boot and no application would query them.
- userState.removeObsoletePrintJobs();
- }
- private void removeUser(int removedUserId) {
- synchronized (mLock) {
- UserState userState = mUserStates.get(removedUserId);
- if (userState != null) {
- userState.destroyLocked();
- mUserStates.remove(removedUserId);
+ private int resolveCallingAppEnforcingPermissions(int appId) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid == 0 || callingUid == Process.SYSTEM_UID
+ || callingUid == Process.SHELL_UID) {
+ return appId;
}
- }
- }
-
- private int resolveCallingAppEnforcingPermissions(int appId) {
- final int callingUid = Binder.getCallingUid();
- if (callingUid == 0 || callingUid == Process.SYSTEM_UID
- || callingUid == Process.SHELL_UID) {
+ final int callingAppId = UserHandle.getAppId(callingUid);
+ if (appId == callingAppId) {
+ return appId;
+ }
+ if (mContext.checkCallingPermission(
+ "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS")
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Call from app " + callingAppId + " as app "
+ + appId + " without com.android.printspooler.permission"
+ + ".ACCESS_ALL_PRINT_JOBS");
+ }
return appId;
}
- final int callingAppId = UserHandle.getAppId(callingUid);
- if (appId == callingAppId) {
- return appId;
- }
- if (mContext.checkCallingPermission(
- "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS")
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Call from app " + callingAppId + " as app "
- + appId + " without com.android.printspooler.permission"
- + ".ACCESS_ALL_PRINT_JOBS");
- }
- return appId;
- }
- private int resolveCallingUserEnforcingPermissions(int userId) {
- final int callingUid = Binder.getCallingUid();
- if (callingUid == 0 || callingUid == Process.SYSTEM_UID
- || callingUid == Process.SHELL_UID) {
- return userId;
- }
- final int callingUserId = UserHandle.getUserId(callingUid);
- if (callingUserId == userId) {
- return userId;
- }
- if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
- != PackageManager.PERMISSION_GRANTED
- || mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
- != PackageManager.PERMISSION_GRANTED) {
- if (userId == UserHandle.USER_CURRENT_OR_SELF) {
- return callingUserId;
+ private int resolveCallingUserEnforcingPermissions(int userId) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid == 0 || callingUid == Process.SYSTEM_UID
+ || callingUid == Process.SHELL_UID) {
+ return userId;
}
- throw new SecurityException("Call from user " + callingUserId + " as user "
- + userId + " without permission INTERACT_ACROSS_USERS or "
- + "INTERACT_ACROSS_USERS_FULL not allowed.");
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ if (callingUserId == userId) {
+ return userId;
+ }
+ if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ != PackageManager.PERMISSION_GRANTED
+ || mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
+ != PackageManager.PERMISSION_GRANTED) {
+ if (userId == UserHandle.USER_CURRENT_OR_SELF) {
+ return callingUserId;
+ }
+ throw new SecurityException("Call from user " + callingUserId + " as user "
+ + userId + " without permission INTERACT_ACROSS_USERS or "
+ + "INTERACT_ACROSS_USERS_FULL not allowed.");
+ }
+ if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) {
+ return mCurrentUserId;
+ }
+ throw new IllegalArgumentException("Calling user can be changed to only "
+ + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
}
- if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) {
- return mCurrentUserId;
- }
- throw new IllegalArgumentException("Calling user can be changed to only "
- + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
- }
- private String resolveCallingPackageNameEnforcingSecurity(String packageName) {
- if (TextUtils.isEmpty(packageName)) {
+ private String resolveCallingPackageNameEnforcingSecurity(String packageName) {
+ if (TextUtils.isEmpty(packageName)) {
+ return null;
+ }
+ String[] packages = mContext.getPackageManager().getPackagesForUid(
+ Binder.getCallingUid());
+ final int packageCount = packages.length;
+ for (int i = 0; i < packageCount; i++) {
+ if (packageName.equals(packages[i])) {
+ return packageName;
+ }
+ }
return null;
}
- String[] packages = mContext.getPackageManager().getPackagesForUid(
- Binder.getCallingUid());
- final int packageCount = packages.length;
- for (int i = 0; i < packageCount; i++) {
- if (packageName.equals(packages[i])) {
- return packageName;
- }
+
+ private void showEnableInstalledPrintServiceNotification(ComponentName component,
+ String label, int userId) {
+ UserHandle userHandle = new UserHandle(userId);
+
+ Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS);
+ intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString());
+
+ PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent,
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null,
+ userHandle);
+
+ Notification.Builder builder = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_print)
+ .setContentTitle(mContext.getString(R.string.print_service_installed_title,
+ label))
+ .setContentText(mContext.getString(R.string.print_service_installed_message))
+ .setContentIntent(pendingIntent)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .setShowWhen(true);
+
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+
+ String notificationTag = getClass().getName() + ":" + component.flattenToString();
+ notificationManager.notifyAsUser(notificationTag, 0, builder.build(),
+ userHandle);
}
- return null;
- }
-
- private void showEnableInstalledPrintServiceNotification(ComponentName component,
- String label, int userId) {
- UserHandle userHandle = new UserHandle(userId);
-
- Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS);
- intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString());
-
- PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent,
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null, userHandle);
-
- Notification.Builder builder = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_print)
- .setContentTitle(mContext.getString(R.string.print_service_installed_title, label))
- .setContentText(mContext.getString(R.string.print_service_installed_message))
- .setContentIntent(pendingIntent)
- .setWhen(System.currentTimeMillis())
- .setAutoCancel(true)
- .setShowWhen(true);
-
- NotificationManager notificationManager = (NotificationManager) mContext
- .getSystemService(Context.NOTIFICATION_SERVICE);
-
- String notificationTag = getClass().getName() + ":" + component.flattenToString();
- notificationManager.notifyAsUser(notificationTag, 0, builder.build(),
- userHandle);
}
}