Merge "Remove the sender package filter from the intent firewall" into jb-mr2-dev
diff --git a/Android.mk b/Android.mk
index 2ad7a72..e70f9f3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -69,7 +69,6 @@
core/java/android/app/IAlarmManager.aidl \
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
- core/java/android/app/INotificationListener.aidl \
core/java/android/app/INotificationManager.aidl \
core/java/android/app/IProcessObserver.aidl \
core/java/android/app/ISearchManager.aidl \
@@ -148,6 +147,7 @@
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
+ core/java/android/service/notification/INotificationListener.aidl \
core/java/android/service/dreams/IDreamManager.aidl \
core/java/android/service/dreams/IDreamService.aidl \
core/java/android/service/wallpaper/IWallpaperConnection.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index fc63866..4debdc2 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -159,6 +159,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/view/IInputMethodCallback.*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/view/IInputMethodSession.*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/view/IInputMethodCallback.*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index 653e25a..1e1f01c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22,6 +22,7 @@
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
+ field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
@@ -2594,6 +2595,10 @@
method public abstract void setDisplayShowHomeEnabled(boolean);
method public abstract void setDisplayShowTitleEnabled(boolean);
method public abstract void setDisplayUseLogoEnabled(boolean);
+ method public void setHomeActionContentDescription(java.lang.CharSequence);
+ method public void setHomeActionContentDescription(int);
+ method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+ method public void setHomeAsUpIndicator(int);
method public void setHomeButtonEnabled(boolean);
method public abstract void setIcon(int);
method public abstract void setIcon(android.graphics.drawable.Drawable);
@@ -18499,10 +18504,6 @@
protected static abstract interface ContactsContract.DataUsageStatColumns {
field public static final java.lang.String LAST_TIME_USED = "last_time_used";
field public static final java.lang.String TIMES_USED = "times_used";
- field public static final java.lang.String USAGE_TYPE = "usage_type";
- field public static final int USAGE_TYPE_CALL = 0; // 0x0
- field public static final int USAGE_TYPE_LONG_TEXT = 1; // 0x1
- field public static final int USAGE_TYPE_SHORT_TEXT = 2; // 0x2
}
public static final class ContactsContract.Directory implements android.provider.BaseColumns {
@@ -19922,29 +19923,6 @@
method public void skip(int);
}
- public deprecated class FileA3D extends android.renderscript.BaseObj {
- method public static deprecated android.renderscript.FileA3D createFromAsset(android.renderscript.RenderScript, android.content.res.AssetManager, java.lang.String);
- method public static deprecated android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.lang.String);
- method public static deprecated android.renderscript.FileA3D createFromFile(android.renderscript.RenderScript, java.io.File);
- method public static deprecated android.renderscript.FileA3D createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int);
- method public deprecated android.renderscript.FileA3D.IndexEntry getIndexEntry(int);
- method public deprecated int getIndexEntryCount();
- }
-
- public static final deprecated class FileA3D.EntryType extends java.lang.Enum {
- method public static android.renderscript.FileA3D.EntryType valueOf(java.lang.String);
- method public static final android.renderscript.FileA3D.EntryType[] values();
- enum_constant public static final deprecated android.renderscript.FileA3D.EntryType MESH;
- enum_constant public static final deprecated android.renderscript.FileA3D.EntryType UNKNOWN;
- }
-
- public static deprecated class FileA3D.IndexEntry {
- method public deprecated android.renderscript.FileA3D.EntryType getEntryType();
- method public deprecated android.renderscript.Mesh getMesh();
- method public deprecated java.lang.String getName();
- method public deprecated android.renderscript.BaseObj getObject();
- }
-
public class Float2 {
ctor public Float2();
ctor public Float2(float, float);
@@ -19969,23 +19947,6 @@
field public float z;
}
- public deprecated class Font extends android.renderscript.BaseObj {
- method public static deprecated android.renderscript.Font create(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, android.renderscript.Font.Style, float);
- method public static deprecated android.renderscript.Font createFromAsset(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
- method public static deprecated android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.lang.String, float);
- method public static deprecated android.renderscript.Font createFromFile(android.renderscript.RenderScript, android.content.res.Resources, java.io.File, float);
- method public static deprecated android.renderscript.Font createFromResource(android.renderscript.RenderScript, android.content.res.Resources, int, float);
- }
-
- public static final deprecated class Font.Style extends java.lang.Enum {
- method public static android.renderscript.Font.Style valueOf(java.lang.String);
- method public static final android.renderscript.Font.Style[] values();
- enum_constant public static final deprecated android.renderscript.Font.Style BOLD;
- enum_constant public static final deprecated android.renderscript.Font.Style BOLD_ITALIC;
- enum_constant public static final deprecated android.renderscript.Font.Style ITALIC;
- enum_constant public static final deprecated android.renderscript.Font.Style NORMAL;
- }
-
public class Int2 {
ctor public Int2();
ctor public Int2(int, int);
@@ -20100,245 +20061,6 @@
method public void transpose();
}
- public deprecated class Mesh extends android.renderscript.BaseObj {
- method public deprecated android.renderscript.Allocation getIndexSetAllocation(int);
- method public deprecated android.renderscript.Mesh.Primitive getPrimitive(int);
- method public deprecated int getPrimitiveCount();
- method public deprecated android.renderscript.Allocation getVertexAllocation(int);
- method public deprecated int getVertexAllocationCount();
- }
-
- public static deprecated class Mesh.AllocationBuilder {
- ctor public deprecated Mesh.AllocationBuilder(android.renderscript.RenderScript);
- method public deprecated android.renderscript.Mesh.AllocationBuilder addIndexSetAllocation(android.renderscript.Allocation, android.renderscript.Mesh.Primitive);
- method public deprecated android.renderscript.Mesh.AllocationBuilder addIndexSetType(android.renderscript.Mesh.Primitive);
- method public deprecated android.renderscript.Mesh.AllocationBuilder addVertexAllocation(android.renderscript.Allocation) throws java.lang.IllegalStateException;
- method public deprecated android.renderscript.Mesh create();
- method public deprecated int getCurrentIndexSetIndex();
- method public deprecated int getCurrentVertexTypeIndex();
- }
-
- public static deprecated class Mesh.Builder {
- ctor public deprecated Mesh.Builder(android.renderscript.RenderScript, int);
- method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
- method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
- method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
- method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
- method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
- method public deprecated android.renderscript.Mesh create();
- method public deprecated int getCurrentIndexSetIndex();
- method public deprecated int getCurrentVertexTypeIndex();
- }
-
- public static final deprecated class Mesh.Primitive extends java.lang.Enum {
- method public static android.renderscript.Mesh.Primitive valueOf(java.lang.String);
- method public static final android.renderscript.Mesh.Primitive[] values();
- enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE;
- enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE_STRIP;
- enum_constant public static final deprecated android.renderscript.Mesh.Primitive POINT;
- enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE;
- enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_FAN;
- enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
- }
-
- public static deprecated class Mesh.TriangleMeshBuilder {
- ctor public deprecated Mesh.TriangleMeshBuilder(android.renderscript.RenderScript, int, int);
- method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addTriangle(int, int, int);
- method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float);
- method public deprecated android.renderscript.Mesh.TriangleMeshBuilder addVertex(float, float, float);
- method public deprecated android.renderscript.Mesh create(boolean);
- method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setColor(float, float, float, float);
- method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setNormal(float, float, float);
- method public deprecated android.renderscript.Mesh.TriangleMeshBuilder setTexture(float, float);
- field public static final deprecated int COLOR = 1; // 0x1
- field public static final deprecated int NORMAL = 2; // 0x2
- field public static final deprecated int TEXTURE_0 = 256; // 0x100
- }
-
- public class Program extends android.renderscript.BaseObj {
- method public void bindConstants(android.renderscript.Allocation, int);
- method public void bindSampler(android.renderscript.Sampler, int) throws java.lang.IllegalArgumentException;
- method public void bindTexture(android.renderscript.Allocation, int) throws java.lang.IllegalArgumentException;
- method public android.renderscript.Type getConstant(int);
- method public int getConstantCount();
- method public int getTextureCount();
- method public java.lang.String getTextureName(int);
- method public android.renderscript.Program.TextureType getTextureType(int);
- }
-
- public static class Program.BaseProgramBuilder {
- ctor protected Program.BaseProgramBuilder(android.renderscript.RenderScript);
- method public android.renderscript.Program.BaseProgramBuilder addConstant(android.renderscript.Type) throws java.lang.IllegalStateException;
- method public android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType) throws java.lang.IllegalArgumentException;
- method public android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType, java.lang.String) throws java.lang.IllegalArgumentException;
- method public int getCurrentConstantIndex();
- method public int getCurrentTextureIndex();
- method protected void initProgram(android.renderscript.Program);
- method public android.renderscript.Program.BaseProgramBuilder setShader(java.lang.String);
- method public android.renderscript.Program.BaseProgramBuilder setShader(android.content.res.Resources, int);
- }
-
- public static final class Program.TextureType extends java.lang.Enum {
- method public static android.renderscript.Program.TextureType valueOf(java.lang.String);
- method public static final android.renderscript.Program.TextureType[] values();
- enum_constant public static final android.renderscript.Program.TextureType TEXTURE_2D;
- enum_constant public static final android.renderscript.Program.TextureType TEXTURE_CUBE;
- }
-
- public deprecated class ProgramFragment extends android.renderscript.Program {
- }
-
- public static deprecated class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
- ctor public deprecated ProgramFragment.Builder(android.renderscript.RenderScript);
- method public deprecated android.renderscript.ProgramFragment create();
- }
-
- public deprecated class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
- }
-
- public static deprecated class ProgramFragmentFixedFunction.Builder {
- ctor public deprecated ProgramFragmentFixedFunction.Builder(android.renderscript.RenderScript);
- method public deprecated android.renderscript.ProgramFragmentFixedFunction create();
- method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setPointSpriteTexCoordinateReplacement(boolean);
- method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setTexture(android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode, android.renderscript.ProgramFragmentFixedFunction.Builder.Format, int) throws java.lang.IllegalArgumentException;
- method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setVaryingColor(boolean);
- field public static final deprecated int MAX_TEXTURE = 2; // 0x2
- }
-
- public static final deprecated class ProgramFragmentFixedFunction.Builder.EnvMode extends java.lang.Enum {
- method public static android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode valueOf(java.lang.String);
- method public static final android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode[] values();
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode DECAL;
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode MODULATE;
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode REPLACE;
- }
-
- public static final deprecated class ProgramFragmentFixedFunction.Builder.Format extends java.lang.Enum {
- method public static android.renderscript.ProgramFragmentFixedFunction.Builder.Format valueOf(java.lang.String);
- method public static final android.renderscript.ProgramFragmentFixedFunction.Builder.Format[] values();
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format ALPHA;
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format LUMINANCE_ALPHA;
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGB;
- enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
- }
-
- public deprecated class ProgramRaster extends android.renderscript.BaseObj {
- method public static deprecated android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
- method public static deprecated android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
- method public static deprecated android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
- method public deprecated android.renderscript.ProgramRaster.CullMode getCullMode();
- method public deprecated boolean isPointSpriteEnabled();
- }
-
- public static deprecated class ProgramRaster.Builder {
- ctor public deprecated ProgramRaster.Builder(android.renderscript.RenderScript);
- method public deprecated android.renderscript.ProgramRaster create();
- method public deprecated android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
- method public deprecated android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
- }
-
- public static final deprecated class ProgramRaster.CullMode extends java.lang.Enum {
- method public static android.renderscript.ProgramRaster.CullMode valueOf(java.lang.String);
- method public static final android.renderscript.ProgramRaster.CullMode[] values();
- enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode BACK;
- enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode FRONT;
- enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode NONE;
- }
-
- public class ProgramStore extends android.renderscript.BaseObj {
- method public static android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_NONE(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_TEST(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramStore BLEND_NONE_DEPTH_NONE(android.renderscript.RenderScript);
- method public static android.renderscript.ProgramStore BLEND_NONE_DEPTH_TEST(android.renderscript.RenderScript);
- method public android.renderscript.ProgramStore.BlendDstFunc getBlendDstFunc();
- method public android.renderscript.ProgramStore.BlendSrcFunc getBlendSrcFunc();
- method public android.renderscript.ProgramStore.DepthFunc getDepthFunc();
- method public boolean isColorMaskAlphaEnabled();
- method public boolean isColorMaskBlueEnabled();
- method public boolean isColorMaskGreenEnabled();
- method public boolean isColorMaskRedEnabled();
- method public boolean isDepthMaskEnabled();
- method public boolean isDitherEnabled();
- }
-
- public static final class ProgramStore.BlendDstFunc extends java.lang.Enum {
- method public static android.renderscript.ProgramStore.BlendDstFunc valueOf(java.lang.String);
- method public static final android.renderscript.ProgramStore.BlendDstFunc[] values();
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc SRC_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ZERO;
- }
-
- public static final class ProgramStore.BlendSrcFunc extends java.lang.Enum {
- method public static android.renderscript.ProgramStore.BlendSrcFunc valueOf(java.lang.String);
- method public static final android.renderscript.ProgramStore.BlendSrcFunc[] values();
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc DST_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_COLOR;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA_SATURATE;
- enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ZERO;
- }
-
- public static class ProgramStore.Builder {
- ctor public ProgramStore.Builder(android.renderscript.RenderScript);
- method public android.renderscript.ProgramStore create();
- method public android.renderscript.ProgramStore.Builder setBlendFunc(android.renderscript.ProgramStore.BlendSrcFunc, android.renderscript.ProgramStore.BlendDstFunc);
- method public android.renderscript.ProgramStore.Builder setColorMaskEnabled(boolean, boolean, boolean, boolean);
- method public android.renderscript.ProgramStore.Builder setDepthFunc(android.renderscript.ProgramStore.DepthFunc);
- method public android.renderscript.ProgramStore.Builder setDepthMaskEnabled(boolean);
- method public android.renderscript.ProgramStore.Builder setDitherEnabled(boolean);
- }
-
- public static final class ProgramStore.DepthFunc extends java.lang.Enum {
- method public static android.renderscript.ProgramStore.DepthFunc valueOf(java.lang.String);
- method public static final android.renderscript.ProgramStore.DepthFunc[] values();
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc ALWAYS;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc EQUAL;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc GREATER;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc GREATER_OR_EQUAL;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc LESS;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc LESS_OR_EQUAL;
- enum_constant public static final android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
- }
-
- public deprecated class ProgramVertex extends android.renderscript.Program {
- method public deprecated android.renderscript.Element getInput(int);
- method public deprecated int getInputCount();
- }
-
- public static deprecated class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
- ctor public deprecated ProgramVertex.Builder(android.renderscript.RenderScript);
- method public deprecated android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
- method public deprecated android.renderscript.ProgramVertex create();
- }
-
- public deprecated class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
- method public deprecated void bindConstants(android.renderscript.ProgramVertexFixedFunction.Constants);
- }
-
- public static deprecated class ProgramVertexFixedFunction.Builder {
- ctor public deprecated ProgramVertexFixedFunction.Builder(android.renderscript.RenderScript);
- method public deprecated android.renderscript.ProgramVertexFixedFunction create();
- method public deprecated android.renderscript.ProgramVertexFixedFunction.Builder setTextureMatrixEnable(boolean);
- }
-
- public static deprecated class ProgramVertexFixedFunction.Constants {
- ctor public deprecated ProgramVertexFixedFunction.Constants(android.renderscript.RenderScript);
- method public deprecated void destroy();
- method public deprecated void setModelview(android.renderscript.Matrix4f);
- method public deprecated void setProjection(android.renderscript.Matrix4f);
- method public deprecated void setTexture(android.renderscript.Matrix4f);
- }
-
public class RSDriverException extends android.renderscript.RSRuntimeException {
ctor public RSDriverException(java.lang.String);
}
@@ -20355,35 +20077,6 @@
ctor public RSRuntimeException(java.lang.String);
}
- public deprecated class RSSurfaceView extends android.view.SurfaceView implements android.view.SurfaceHolder.Callback {
- ctor public deprecated RSSurfaceView(android.content.Context);
- ctor public deprecated RSSurfaceView(android.content.Context, android.util.AttributeSet);
- method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public deprecated void destroyRenderScriptGL();
- method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
- method public deprecated void pause();
- method public deprecated void resume();
- method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
- method public deprecated void surfaceChanged(android.view.SurfaceHolder, int, int, int);
- method public deprecated void surfaceCreated(android.view.SurfaceHolder);
- method public deprecated void surfaceDestroyed(android.view.SurfaceHolder);
- }
-
- public deprecated class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
- ctor public deprecated RSTextureView(android.content.Context);
- ctor public deprecated RSTextureView(android.content.Context, android.util.AttributeSet);
- method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public deprecated void destroyRenderScriptGL();
- method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
- method public deprecated void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
- method public deprecated boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
- method public deprecated void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
- method public deprecated void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
- method public deprecated void pause();
- method public deprecated void resume();
- method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
- }
-
public class RenderScript {
method public void contextDump();
method public static android.renderscript.RenderScript create(android.content.Context);
@@ -20427,30 +20120,6 @@
field protected int mLength;
}
- public deprecated class RenderScriptGL extends android.renderscript.RenderScript {
- ctor public deprecated RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
- method public deprecated void bindProgramFragment(android.renderscript.ProgramFragment);
- method public deprecated void bindProgramRaster(android.renderscript.ProgramRaster);
- method public deprecated void bindProgramStore(android.renderscript.ProgramStore);
- method public deprecated void bindProgramVertex(android.renderscript.ProgramVertex);
- method public deprecated void bindRootScript(android.renderscript.Script);
- method public deprecated int getHeight();
- method public deprecated int getWidth();
- method public deprecated void pause();
- method public deprecated void resume();
- method public deprecated void setSurface(android.view.SurfaceHolder, int, int);
- method public deprecated void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
- }
-
- public static deprecated class RenderScriptGL.SurfaceConfig {
- ctor public deprecated RenderScriptGL.SurfaceConfig();
- ctor public deprecated RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
- method public deprecated void setAlpha(int, int);
- method public deprecated void setColor(int, int);
- method public deprecated void setDepth(int, int);
- method public deprecated void setSamples(int, int, float);
- }
-
public class Sampler extends android.renderscript.BaseObj {
method public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
method public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
@@ -20764,6 +20433,19 @@
package android.security {
+ public class AndroidKeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ }
+
+ public static class AndroidKeyPairGeneratorSpec.Builder {
+ ctor public AndroidKeyPairGeneratorSpec.Builder(android.content.Context);
+ method public android.security.AndroidKeyPairGeneratorSpec build();
+ method public android.security.AndroidKeyPairGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.AndroidKeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.AndroidKeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
+ method public android.security.AndroidKeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
+ method public android.security.AndroidKeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+ }
+
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
@@ -20839,6 +20521,38 @@
}
+package android.service.notification {
+
+ public abstract class NotificationListenerService extends android.app.Service {
+ ctor public NotificationListenerService();
+ method public final void clearAllNotifications();
+ method public final void clearNotification(java.lang.String, java.lang.String, int);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onNotificationPosted(android.service.notification.StatusBarNotification);
+ method public abstract void onNotificationRemoved(android.service.notification.StatusBarNotification);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
+ }
+
+ public class StatusBarNotification implements android.os.Parcelable {
+ ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long);
+ ctor public StatusBarNotification(android.os.Parcel);
+ method public android.service.notification.StatusBarNotification clone();
+ method public int describeContents();
+ method public int getUserId();
+ method public boolean isClearable();
+ method public boolean isOngoing();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public final int id;
+ field public final android.app.Notification notification;
+ field public final java.lang.String pkg;
+ field public final long postTime;
+ field public final java.lang.String tag;
+ field public final android.os.UserHandle user;
+ }
+
+}
+
package android.service.textservice {
public abstract class SpellCheckerService extends android.app.Service {
@@ -24490,6 +24204,7 @@
method public float getMax();
method public float getMin();
method public float getRange();
+ method public float getResolution();
method public int getSource();
method public boolean isFromSource(int);
}
@@ -25247,14 +24962,6 @@
field public static final int ORIENTATION_UNKNOWN = -1; // 0xffffffff
}
- public abstract interface Overlay {
- method public abstract void add(android.graphics.drawable.Drawable);
- method public abstract void add(android.view.View);
- method public abstract void clear();
- method public abstract void remove(android.graphics.drawable.Drawable);
- method public abstract void remove(android.view.View);
- }
-
public class ScaleGestureDetector {
ctor public ScaleGestureDetector(android.content.Context, android.view.ScaleGestureDetector.OnScaleGestureListener);
method public float getCurrentSpan();
@@ -25559,7 +25266,7 @@
method public int getNextFocusUpId();
method public android.view.View.OnFocusChangeListener getOnFocusChangeListener();
method public int getOverScrollMode();
- method public android.view.Overlay getOverlay();
+ method public android.view.ViewOverlay getOverlay();
method public int getPaddingBottom();
method public int getPaddingEnd();
method public int getPaddingLeft();
@@ -26300,12 +26007,23 @@
method public abstract void onChildViewRemoved(android.view.View, android.view.View);
}
+ public class ViewGroupOverlay extends android.view.ViewOverlay {
+ method public void add(android.view.View);
+ method public void remove(android.view.View);
+ }
+
public abstract interface ViewManager {
method public abstract void addView(android.view.View, android.view.ViewGroup.LayoutParams);
method public abstract void removeView(android.view.View);
method public abstract void updateViewLayout(android.view.View, android.view.ViewGroup.LayoutParams);
}
+ public class ViewOverlay {
+ method public void add(android.graphics.drawable.Drawable);
+ method public void clear();
+ method public void remove(android.graphics.drawable.Drawable);
+ }
+
public abstract interface ViewParent {
method public abstract void bringChildToFront(android.view.View);
method public abstract void childDrawableStateChanged(android.view.View);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 1c02960..ccb9e1f 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -39,6 +39,7 @@
import android.os.UserHandle;
import android.util.AndroidException;
import android.view.IWindowManager;
+import com.android.internal.os.BaseCommand;
import java.io.BufferedReader;
import java.io.File;
@@ -50,12 +51,9 @@
import java.util.HashSet;
import java.util.List;
-public class Am {
+public class Am extends BaseCommand {
private IActivityManager mAm;
- private String[] mArgs;
- private int mNextArg;
- private String mCurArgData;
private int mStartFlags = 0;
private boolean mWaitOption = false;
@@ -67,33 +65,155 @@
private String mProfileFile;
- // These are magic strings understood by the Eclipse plugin.
- private static final String FATAL_ERROR_CODE = "Error type 1";
- private static final String NO_SYSTEM_ERROR_CODE = "Error type 2";
- private static final String NO_CLASS_ERROR_CODE = "Error type 3";
-
/**
* Command-line entry point.
*
* @param args The command-line arguments
*/
public static void main(String[] args) {
- try {
- (new Am()).run(args);
- } catch (IllegalArgumentException e) {
- showUsage();
- System.err.println("Error: " + e.getMessage());
- } catch (Exception e) {
- e.printStackTrace(System.err);
- System.exit(1);
- }
+ (new Am()).run(args);
}
- private void run(String[] args) throws Exception {
- if (args.length < 1) {
- showUsage();
- return;
- }
+ public void onShowUsage(PrintStream out) {
+ out.println(
+ "usage: am [subcommand] [options]\n" +
+ "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
+ " [--R COUNT] [-S] [--opengl-trace]\n" +
+ " [--user <USER_ID> | current] <INTENT>\n" +
+ " am startservice [--user <USER_ID> | current] <INTENT>\n" +
+ " am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
+ " am kill [--user <USER_ID> | all | current] <PACKAGE>\n" +
+ " am kill-all\n" +
+ " am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
+ " am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
+ " [--user <USER_ID> | current]\n" +
+ " [--no-window-animation] <COMPONENT>\n" +
+ " am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
+ " am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
+ " am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
+ " am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
+ " am clear-debug-app\n" +
+ " am monitor [--gdb <port>]\n" +
+ " am screen-compat [on|off] <PACKAGE>\n" +
+ " am to-uri [INTENT]\n" +
+ " am to-intent-uri [INTENT]\n" +
+ " am switch-user <USER_ID>\n" +
+ " am stop-user <USER_ID>\n" +
+ "\n" +
+ "am start: start an Activity. Options are:\n" +
+ " -D: enable debugging\n" +
+ " -W: wait for launch to complete\n" +
+ " --start-profiler <FILE>: start profiler and send results to <FILE>\n" +
+ " -P <FILE>: like above, but profiling stops when app goes idle\n" +
+ " -R: repeat the activity launch <COUNT> times. Prior to each repeat,\n" +
+ " the top activity will be finished.\n" +
+ " -S: force stop the target app before starting the activity\n" +
+ " --opengl-trace: enable tracing of OpenGL functions\n" +
+ " --user <USER_ID> | current: Specify which user to run as; if not\n" +
+ " specified then run as the current user.\n" +
+ "\n" +
+ "am startservice: start a Service. Options are:\n" +
+ " --user <USER_ID> | current: Specify which user to run as; if not\n" +
+ " specified then run as the current user.\n" +
+ "\n" +
+ "am force-stop: force stop everything associated with <PACKAGE>.\n" +
+ " --user <USER_ID> | all | current: Specify user to force stop;\n" +
+ " all users if not specified.\n" +
+ "\n" +
+ "am kill: Kill all processes associated with <PACKAGE>. Only kills.\n" +
+ " processes that are safe to kill -- that is, will not impact the user\n" +
+ " experience.\n" +
+ " --user <USER_ID> | all | current: Specify user whose processes to kill;\n" +
+ " all users if not specified.\n" +
+ "\n" +
+ "am kill-all: Kill all background processes.\n" +
+ "\n" +
+ "am broadcast: send a broadcast Intent. Options are:\n" +
+ " --user <USER_ID> | all | current: Specify which user to send to; if not\n" +
+ " specified then send to all users.\n" +
+ " --receiver-permission <PERMISSION>: Require receiver to hold permission.\n" +
+ "\n" +
+ "am instrument: start an Instrumentation. Typically this target <COMPONENT>\n" +
+ " is the form <TEST_PACKAGE>/<RUNNER_CLASS>. Options are:\n" +
+ " -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with\n" +
+ " [-e perf true] to generate raw output for performance measurements.\n" +
+ " -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a\n" +
+ " common form is [-e <testrunner_flag> <value>[,<value>...]].\n" +
+ " -p <FILE>: write profiling data to <FILE>\n" +
+ " -w: wait for instrumentation to finish before returning. Required for\n" +
+ " test runners.\n" +
+ " --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
+ " current user if not specified.\n" +
+ " --no-window-animation: turn off window animations will running.\n" +
+ "\n" +
+ "am profile: start and stop profiler on a process. The given <PROCESS> argument\n" +
+ " may be either a process name or pid. Options are:\n" +
+ " --user <USER_ID> | current: When supplying a process name,\n" +
+ " specify user of process to profile; uses current user if not specified.\n" +
+ "\n" +
+ "am dumpheap: dump the heap of a process. The given <PROCESS> argument may\n" +
+ " be either a process name or pid. Options are:\n" +
+ " -n: dump native heap instead of managed heap\n" +
+ " --user <USER_ID> | current: When supplying a process name,\n" +
+ " specify user of process to dump; uses current user if not specified.\n" +
+ "\n" +
+ "am set-debug-app: set application <PACKAGE> to debug. Options are:\n" +
+ " -w: wait for debugger when application starts\n" +
+ " --persistent: retain this value\n" +
+ "\n" +
+ "am clear-debug-app: clear the previously set-debug-app.\n" +
+ "\n" +
+ "am bug-report: request bug report generation; will launch UI\n" +
+ " when done to select where it should be delivered.\n" +
+ "\n" +
+ "am monitor: start monitoring for crashes or ANRs.\n" +
+ " --gdb: start gdbserv on the given port at crash/ANR\n" +
+ "\n" +
+ "am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
+ "\n" +
+ "am to-uri: print the given Intent specification as a URI.\n" +
+ "\n" +
+ "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
+ "\n" +
+ "am switch-user: switch to put USER_ID in the foreground, starting\n" +
+ " execution of that user if it is currently stopped.\n" +
+ "\n" +
+ "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
+ " code until a later explicit switch to it.\n" +
+ "\n" +
+ "<INTENT> specifications include these flags and arguments:\n" +
+ " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
+ " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
+ " [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]\n" +
+ " [--esn <EXTRA_KEY> ...]\n" +
+ " [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" +
+ " [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" +
+ " [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" +
+ " [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]\n" +
+ " [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" +
+ " [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" +
+ " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
+ " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
+ " [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
+ " [-n <COMPONENT>] [-f <FLAGS>]\n" +
+ " [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
+ " [--debug-log-resolution] [--exclude-stopped-packages]\n" +
+ " [--include-stopped-packages]\n" +
+ " [--activity-brought-to-front] [--activity-clear-top]\n" +
+ " [--activity-clear-when-task-reset] [--activity-exclude-from-recents]\n" +
+ " [--activity-launched-from-history] [--activity-multiple-task]\n" +
+ " [--activity-no-animation] [--activity-no-history]\n" +
+ " [--activity-no-user-action] [--activity-previous-is-top]\n" +
+ " [--activity-reorder-to-front] [--activity-reset-task-if-needed]\n" +
+ " [--activity-single-top] [--activity-clear-task]\n" +
+ " [--activity-task-on-home]\n" +
+ " [--receiver-registered-only] [--receiver-replace-pending]\n" +
+ " [--selector]\n" +
+ " [<URI> | <PACKAGE> | <COMPONENT>]\n"
+ );
+ }
+
+ public void onRun() throws Exception {
mAm = ActivityManagerNative.getDefault();
if (mAm == null) {
@@ -101,9 +221,7 @@
throw new AndroidException("Can't connect to activity manager; is the system running?");
}
- mArgs = args;
- String op = args[0];
- mNextArg = 1;
+ String op = nextArgRequired();
if (op.equals("start")) {
runStart();
@@ -142,7 +260,7 @@
} else if (op.equals("stop-user")) {
runStopUser();
} else {
- throw new IllegalArgumentException("Unknown command: " + op);
+ showError("Error: unknown command '" + op + "'");
}
}
@@ -1303,193 +1421,4 @@
return true;
}
}
-
- private String nextOption() {
- if (mCurArgData != null) {
- String prev = mArgs[mNextArg - 1];
- throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
- }
- if (mNextArg >= mArgs.length) {
- return null;
- }
- String arg = mArgs[mNextArg];
- if (!arg.startsWith("-")) {
- return null;
- }
- mNextArg++;
- if (arg.equals("--")) {
- return null;
- }
- if (arg.length() > 1 && arg.charAt(1) != '-') {
- if (arg.length() > 2) {
- mCurArgData = arg.substring(2);
- return arg.substring(0, 2);
- } else {
- mCurArgData = null;
- return arg;
- }
- }
- mCurArgData = null;
- return arg;
- }
-
- private String nextArg() {
- if (mCurArgData != null) {
- String arg = mCurArgData;
- mCurArgData = null;
- return arg;
- } else if (mNextArg < mArgs.length) {
- return mArgs[mNextArg++];
- } else {
- return null;
- }
- }
-
- private String nextArgRequired() {
- String arg = nextArg();
- if (arg == null) {
- String prev = mArgs[mNextArg - 1];
- throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
- }
- return arg;
- }
-
- private static void showUsage() {
- System.err.println(
- "usage: am [subcommand] [options]\n" +
- "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
- " [--R COUNT] [-S] [--opengl-trace]\n" +
- " [--user <USER_ID> | current] <INTENT>\n" +
- " am startservice [--user <USER_ID> | current] <INTENT>\n" +
- " am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
- " am kill [--user <USER_ID> | all | current] <PACKAGE>\n" +
- " am kill-all\n" +
- " am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
- " am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
- " [--user <USER_ID> | current]\n" +
- " [--no-window-animation] <COMPONENT>\n" +
- " am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" +
- " am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
- " am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
- " am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
- " am clear-debug-app\n" +
- " am monitor [--gdb <port>]\n" +
- " am screen-compat [on|off] <PACKAGE>\n" +
- " am to-uri [INTENT]\n" +
- " am to-intent-uri [INTENT]\n" +
- " am switch-user <USER_ID>\n" +
- " am stop-user <USER_ID>\n" +
- "\n" +
- "am start: start an Activity. Options are:\n" +
- " -D: enable debugging\n" +
- " -W: wait for launch to complete\n" +
- " --start-profiler <FILE>: start profiler and send results to <FILE>\n" +
- " -P <FILE>: like above, but profiling stops when app goes idle\n" +
- " -R: repeat the activity launch <COUNT> times. Prior to each repeat,\n" +
- " the top activity will be finished.\n" +
- " -S: force stop the target app before starting the activity\n" +
- " --opengl-trace: enable tracing of OpenGL functions\n" +
- " --user <USER_ID> | current: Specify which user to run as; if not\n" +
- " specified then run as the current user.\n" +
- "\n" +
- "am startservice: start a Service. Options are:\n" +
- " --user <USER_ID> | current: Specify which user to run as; if not\n" +
- " specified then run as the current user.\n" +
- "\n" +
- "am force-stop: force stop everything associated with <PACKAGE>.\n" +
- " --user <USER_ID> | all | current: Specify user to force stop;\n" +
- " all users if not specified.\n" +
- "\n" +
- "am kill: Kill all processes associated with <PACKAGE>. Only kills.\n" +
- " processes that are safe to kill -- that is, will not impact the user\n" +
- " experience.\n" +
- " --user <USER_ID> | all | current: Specify user whose processes to kill;\n" +
- " all users if not specified.\n" +
- "\n" +
- "am kill-all: Kill all background processes.\n" +
- "\n" +
- "am broadcast: send a broadcast Intent. Options are:\n" +
- " --user <USER_ID> | all | current: Specify which user to send to; if not\n" +
- " specified then send to all users.\n" +
- " --receiver-permission <PERMISSION>: Require receiver to hold permission.\n" +
- "\n" +
- "am instrument: start an Instrumentation. Typically this target <COMPONENT>\n" +
- " is the form <TEST_PACKAGE>/<RUNNER_CLASS>. Options are:\n" +
- " -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with\n" +
- " [-e perf true] to generate raw output for performance measurements.\n" +
- " -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a\n" +
- " common form is [-e <testrunner_flag> <value>[,<value>...]].\n" +
- " -p <FILE>: write profiling data to <FILE>\n" +
- " -w: wait for instrumentation to finish before returning. Required for\n" +
- " test runners.\n" +
- " --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
- " current user if not specified.\n" +
- " --no-window-animation: turn off window animations will running.\n" +
- "\n" +
- "am profile: start and stop profiler on a process. The given <PROCESS> argument\n" +
- " may be either a process name or pid. Options are:\n" +
- " --user <USER_ID> | current: When supplying a process name,\n" +
- " specify user of process to profile; uses current user if not specified.\n" +
- "\n" +
- "am dumpheap: dump the heap of a process. The given <PROCESS> argument may\n" +
- " be either a process name or pid. Options are:\n" +
- " -n: dump native heap instead of managed heap\n" +
- " --user <USER_ID> | current: When supplying a process name,\n" +
- " specify user of process to dump; uses current user if not specified.\n" +
- "\n" +
- "am set-debug-app: set application <PACKAGE> to debug. Options are:\n" +
- " -w: wait for debugger when application starts\n" +
- " --persistent: retain this value\n" +
- "\n" +
- "am clear-debug-app: clear the previously set-debug-app.\n" +
- "\n" +
- "am bug-report: request bug report generation; will launch UI\n" +
- " when done to select where it should be delivered.\n" +
- "\n" +
- "am monitor: start monitoring for crashes or ANRs.\n" +
- " --gdb: start gdbserv on the given port at crash/ANR\n" +
- "\n" +
- "am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
- "\n" +
- "am to-uri: print the given Intent specification as a URI.\n" +
- "\n" +
- "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
- "\n" +
- "am switch-user: switch to put USER_ID in the foreground, starting\n" +
- " execution of that user if it is currently stopped.\n" +
- "\n" +
- "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
- " code until a later explicit switch to it.\n" +
- "\n" +
- "<INTENT> specifications include these flags and arguments:\n" +
- " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
- " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
- " [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]\n" +
- " [--esn <EXTRA_KEY> ...]\n" +
- " [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" +
- " [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" +
- " [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" +
- " [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]\n" +
- " [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" +
- " [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" +
- " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
- " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
- " [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
- " [-n <COMPONENT>] [-f <FLAGS>]\n" +
- " [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
- " [--debug-log-resolution] [--exclude-stopped-packages]\n" +
- " [--include-stopped-packages]\n" +
- " [--activity-brought-to-front] [--activity-clear-top]\n" +
- " [--activity-clear-when-task-reset] [--activity-exclude-from-recents]\n" +
- " [--activity-launched-from-history] [--activity-multiple-task]\n" +
- " [--activity-no-animation] [--activity-no-history]\n" +
- " [--activity-no-user-action] [--activity-previous-is-top]\n" +
- " [--activity-reorder-to-front] [--activity-reset-task-if-needed]\n" +
- " [--activity-single-top] [--activity-clear-task]\n" +
- " [--activity-task-on-home]\n" +
- " [--receiver-registered-only] [--receiver-replace-pending]\n" +
- " [--selector]\n" +
- " [<URI> | <PACKAGE> | <COMPONENT>]\n"
- );
- }
}
diff --git a/cmds/media/Android.mk b/cmds/media/Android.mk
new file mode 100644
index 0000000..b9451c5
--- /dev/null
+++ b/cmds/media/Android.mk
@@ -0,0 +1,15 @@
+# Copyright 2013 The Android Open Source Project
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := media_cmd
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := media
+LOCAL_SRC_FILES := media
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
diff --git a/cmds/media/MODULE_LICENSE_APACHE2 b/cmds/media/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/media/MODULE_LICENSE_APACHE2
diff --git a/cmds/media/NOTICE b/cmds/media/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/cmds/media/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/cmds/media/media b/cmds/media/media
new file mode 100755
index 0000000..1194442
--- /dev/null
+++ b/cmds/media/media
@@ -0,0 +1,6 @@
+# Script to start "media_cmd" on the device, which has a very rudimentary
+# shell.
+#
+base=/system
+export CLASSPATH=$base/framework/media_cmd.jar
+exec app_process $base/bin com.android.commands.media.Media "$@"
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
new file mode 100644
index 0000000..56af7d6
--- /dev/null
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -0,0 +1,220 @@
+/*
+**
+** Copyright 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.commands.media;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.media.IAudioService;
+import android.media.IRemoteControlDisplay;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.AndroidException;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import com.android.internal.os.BaseCommand;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+public class Media extends BaseCommand {
+
+ private IAudioService mAudioService;
+
+ /**
+ * Command-line entry point.
+ *
+ * @param args The command-line arguments
+ */
+ public static void main(String[] args) {
+ (new Media()).run(args);
+ }
+
+ public void onShowUsage(PrintStream out) {
+ out.println(
+ "usage: media [subcommand] [options]\n" +
+ " media dispatch KEY\n" +
+ " media remote-display\n" +
+ "\n" +
+ "media dispatch: dispatch a media key to the current media client.\n" +
+ " KEY may be: play, pause, play-pause, mute, headsethook,\n" +
+ " stop, next, previous, rewind, recordm fast-forword.\n" +
+ "media remote-display: monitor remote display updates.\n"
+ );
+ }
+
+ public void onRun() throws Exception {
+ mAudioService = IAudioService.Stub.asInterface(ServiceManager.checkService(
+ Context.AUDIO_SERVICE));
+ if (mAudioService == null) {
+ System.err.println(NO_SYSTEM_ERROR_CODE);
+ throw new AndroidException("Can't connect to audio service; is the system running?");
+ }
+
+ String op = nextArgRequired();
+
+ if (op.equals("dispatch")) {
+ runDispatch();
+ } else if (op.equals("remote-display")) {
+ runRemoteDisplay();
+ } else {
+ showError("Error: unknown command '" + op + "'");
+ return;
+ }
+ }
+
+ private void sendMediaKey(KeyEvent event) {
+ try {
+ mAudioService.dispatchMediaKeyEvent(event);
+ } catch (RemoteException e) {
+ }
+ }
+
+ private void runDispatch() throws Exception {
+ String cmd = nextArgRequired();
+ int keycode;
+ if ("play".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_PLAY;
+ } else if ("pause".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_PAUSE;
+ } else if ("play-pause".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
+ } else if ("mute".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MUTE;
+ } else if ("headsethook".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_HEADSETHOOK;
+ } else if ("stop".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_STOP;
+ } else if ("next".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_NEXT;
+ } else if ("previous".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
+ } else if ("rewind".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_REWIND;
+ } else if ("record".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_RECORD;
+ } else if ("fast-forward".equals(cmd)) {
+ keycode = KeyEvent.KEYCODE_MEDIA_FAST_FORWARD;
+ } else {
+ showError("Error: unknown dispatch code '" + cmd + "'");
+ return;
+ }
+
+ final long now = SystemClock.uptimeMillis();
+ sendMediaKey(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+ sendMediaKey(new KeyEvent(now, now, KeyEvent.ACTION_UP, keycode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+ }
+
+ class RemoteDisplayMonitor extends IRemoteControlDisplay.Stub {
+ RemoteDisplayMonitor() {
+ }
+
+
+ @Override
+ public void setCurrentClientId(int clientGeneration, PendingIntent clientMediaIntent,
+ boolean clearing) {
+ System.out.println("New client: id=" + clientGeneration
+ + " intent=" + clientMediaIntent + " clearing=" + clearing);
+ }
+
+ @Override
+ public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
+ long currentPosMs, float speed) {
+ System.out.println("New state: id=" + generationId + " state=" + state
+ + " time=" + stateChangeTimeMs + " pos=" + currentPosMs + " speed=" + speed);
+ }
+
+ @Override
+ public void setTransportControlInfo(int generationId, int transportControlFlags,
+ int posCapabilities) {
+ System.out.println("New control info: id=" + generationId
+ + " flags=0x" + Integer.toHexString(transportControlFlags)
+ + " cap=0x" + Integer.toHexString(posCapabilities));
+ }
+
+ @Override
+ public void setMetadata(int generationId, Bundle metadata) {
+ System.out.println("New metadata: id=" + generationId
+ + " data=" + metadata);
+ }
+
+ @Override
+ public void setArtwork(int generationId, Bitmap artwork) {
+ System.out.println("New artwork: id=" + generationId
+ + " art=" + artwork);
+ }
+
+ @Override
+ public void setAllMetadata(int generationId, Bundle metadata, Bitmap artwork) {
+ System.out.println("New metadata+artwork: id=" + generationId
+ + " data=" + metadata + " art=" + artwork);
+ }
+
+ void printUsageMessage() {
+ System.out.println("Monitoring remote control displays... available commands:");
+ System.out.println("(q)uit: finish monitoring");
+ }
+
+ void run() throws RemoteException {
+ printUsageMessage();
+
+ mAudioService.registerRemoteControlDisplay(this, 0, 0);
+
+ try {
+ InputStreamReader converter = new InputStreamReader(System.in);
+ BufferedReader in = new BufferedReader(converter);
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ boolean addNewline = true;
+ if (line.length() <= 0) {
+ addNewline = false;
+ } else if ("q".equals(line) || "quit".equals(line)) {
+ break;
+ } else {
+ System.out.println("Invalid command: " + line);
+ }
+
+ synchronized (this) {
+ if (addNewline) {
+ System.out.println("");
+ }
+ printUsageMessage();
+ }
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ mAudioService.unregisterRemoteControlDisplay(this);
+ }
+ }
+ }
+
+ private void runRemoteDisplay() throws Exception {
+ RemoteDisplayMonitor monitor = new RemoteDisplayMonitor();
+ monitor.run();
+ }
+}
diff --git a/cmds/wm/src/com/android/commands/wm/Wm.java b/cmds/wm/src/com/android/commands/wm/Wm.java
index 31eba96..815a0ac 100644
--- a/cmds/wm/src/com/android/commands/wm/Wm.java
+++ b/cmds/wm/src/com/android/commands/wm/Wm.java
@@ -26,21 +26,15 @@
import android.util.AndroidException;
import android.view.Display;
import android.view.IWindowManager;
+import com.android.internal.os.BaseCommand;
+import java.io.PrintStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class Wm {
+public class Wm extends BaseCommand {
private IWindowManager mWm;
- private String[] mArgs;
- private int mNextArg;
- private String mCurArgData;
-
- // These are magic strings understood by the Eclipse plugin.
- private static final String FATAL_ERROR_CODE = "Error type 1";
- private static final String NO_SYSTEM_ERROR_CODE = "Error type 2";
- private static final String NO_CLASS_ERROR_CODE = "Error type 3";
/**
* Command-line entry point.
@@ -48,23 +42,25 @@
* @param args The command-line arguments
*/
public static void main(String[] args) {
- try {
- (new Wm()).run(args);
- } catch (IllegalArgumentException e) {
- showUsage();
- System.err.println("Error: " + e.getMessage());
- } catch (Exception e) {
- e.printStackTrace(System.err);
- System.exit(1);
- }
+ (new Wm()).run(args);
}
- private void run(String[] args) throws Exception {
- if (args.length < 1) {
- showUsage();
- return;
- }
+ public void onShowUsage(PrintStream out) {
+ out.println(
+ "usage: wm [subcommand] [options]\n" +
+ " wm size [reset|WxH]\n" +
+ " wm density [reset|DENSITY]\n" +
+ " wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
+ "\n" +
+ "wm size: return or override display size.\n" +
+ "\n" +
+ "wm density: override display density.\n" +
+ "\n" +
+ "wm overscan: set overscan area for display.\n"
+ );
+ }
+ public void onRun() throws Exception {
mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
Context.WINDOW_SERVICE));
if (mWm == null) {
@@ -72,9 +68,7 @@
throw new AndroidException("Can't connect to window manager; is the system running?");
}
- mArgs = args;
- String op = args[0];
- mNextArg = 1;
+ String op = nextArgRequired();
if (op.equals("size")) {
runDisplaySize();
@@ -83,7 +77,8 @@
} else if (op.equals("overscan")) {
runDisplayOverscan();
} else {
- throw new IllegalArgumentException("Unknown command: " + op);
+ showError("Error: unknown command '" + op + "'");
+ return;
}
}
@@ -198,69 +193,4 @@
} catch (RemoteException e) {
}
}
-
- private String nextOption() {
- if (mCurArgData != null) {
- String prev = mArgs[mNextArg - 1];
- throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
- }
- if (mNextArg >= mArgs.length) {
- return null;
- }
- String arg = mArgs[mNextArg];
- if (!arg.startsWith("-")) {
- return null;
- }
- mNextArg++;
- if (arg.equals("--")) {
- return null;
- }
- if (arg.length() > 1 && arg.charAt(1) != '-') {
- if (arg.length() > 2) {
- mCurArgData = arg.substring(2);
- return arg.substring(0, 2);
- } else {
- mCurArgData = null;
- return arg;
- }
- }
- mCurArgData = null;
- return arg;
- }
-
- private String nextArg() {
- if (mCurArgData != null) {
- String arg = mCurArgData;
- mCurArgData = null;
- return arg;
- } else if (mNextArg < mArgs.length) {
- return mArgs[mNextArg++];
- } else {
- return null;
- }
- }
-
- private String nextArgRequired() {
- String arg = nextArg();
- if (arg == null) {
- String prev = mArgs[mNextArg - 1];
- throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
- }
- return arg;
- }
-
- private static void showUsage() {
- System.err.println(
- "usage: wm [subcommand] [options]\n" +
- " wm size [reset|WxH]\n" +
- " wm density [reset|DENSITY]\n" +
- " wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
- "\n" +
- "wm size: return or override display size.\n" +
- "\n" +
- "wm density: override display density.\n" +
- "\n" +
- "wm overscan: set overscan area for display.\n"
- );
- }
}
diff --git a/core/java/android/animation/RectEvaluator.java b/core/java/android/animation/RectEvaluator.java
index 10932bb..28d496b 100644
--- a/core/java/android/animation/RectEvaluator.java
+++ b/core/java/android/animation/RectEvaluator.java
@@ -18,7 +18,7 @@
import android.graphics.Rect;
/**
- * This evaluator can be used to perform type interpolation between <code>int</code> values.
+ * This evaluator can be used to perform type interpolation between <code>Rect</code> values.
*/
public class RectEvaluator implements TypeEvaluator<Rect> {
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 3602fc4..c4ddf1f 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -695,6 +695,86 @@
public boolean isTitleTruncated() { return false; }
/**
+ * Set an alternate drawable to display next to the icon/logo/title
+ * when {@link #DISPLAY_HOME_AS_UP} is enabled. This can be useful if you are using
+ * this mode to display an alternate selection for up navigation, such as a sliding drawer.
+ *
+ * <p>If you pass <code>null</code> to this method, the default drawable from the theme
+ * will be used.</p>
+ *
+ * <p>If you implement alternate or intermediate behavior around Up, you should also
+ * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()}
+ * to provide a correct description of the action for accessibility support.</p>
+ *
+ * @param indicator A drawable to use for the up indicator, or null to use the theme's default
+ *
+ * @see #setDisplayOptions(int, int)
+ * @see #setDisplayHomeAsUpEnabled(boolean)
+ * @see #setHomeActionContentDescription(int)
+ */
+ public void setHomeAsUpIndicator(Drawable indicator) { }
+
+ /**
+ * Set an alternate drawable to display next to the icon/logo/title
+ * when {@link #DISPLAY_HOME_AS_UP} is enabled. This can be useful if you are using
+ * this mode to display an alternate selection for up navigation, such as a sliding drawer.
+ *
+ * <p>If you pass <code>0</code> to this method, the default drawable from the theme
+ * will be used.</p>
+ *
+ * <p>If you implement alternate or intermediate behavior around Up, you should also
+ * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()}
+ * to provide a correct description of the action for accessibility support.</p>
+ *
+ * @param resId Resource ID of a drawable to use for the up indicator, or null
+ * to use the theme's default
+ *
+ * @see #setDisplayOptions(int, int)
+ * @see #setDisplayHomeAsUpEnabled(boolean)
+ * @see #setHomeActionContentDescription(int)
+ */
+ public void setHomeAsUpIndicator(int resId) { }
+
+ /**
+ * Set an alternate description for the Home/Up action, when enabled.
+ *
+ * <p>This description is commonly used for accessibility/screen readers when
+ * the Home action is enabled. (See {@link #setDisplayHomeAsUpEnabled(boolean)}.)
+ * Examples of this are, "Navigate Home" or "Navigate Up" depending on the
+ * {@link #DISPLAY_HOME_AS_UP} display option. If you have changed the home-as-up
+ * indicator using {@link #setHomeAsUpIndicator(int)} to indicate more specific
+ * functionality such as a sliding drawer, you should also set this to accurately
+ * describe the action.</p>
+ *
+ * <p>Setting this to <code>null</code> will use the system default description.</p>
+ *
+ * @param description New description for the Home action when enabled
+ * @see #setHomeAsUpIndicator(int)
+ * @see #setHomeAsUpIndicator(android.graphics.drawable.Drawable)
+ */
+ public void setHomeActionContentDescription(CharSequence description) { }
+
+ /**
+ * Set an alternate description for the Home/Up action, when enabled.
+ *
+ * <p>This description is commonly used for accessibility/screen readers when
+ * the Home action is enabled. (See {@link #setDisplayHomeAsUpEnabled(boolean)}.)
+ * Examples of this are, "Navigate Home" or "Navigate Up" depending on the
+ * {@link #DISPLAY_HOME_AS_UP} display option. If you have changed the home-as-up
+ * indicator using {@link #setHomeAsUpIndicator(int)} to indicate more specific
+ * functionality such as a sliding drawer, you should also set this to accurately
+ * describe the action.</p>
+ *
+ * <p>Setting this to <code>0</code> will use the system default description.</p>
+ *
+ * @param resId Resource ID of a string to use as the new description
+ * for the Home action when enabled
+ * @see #setHomeAsUpIndicator(int)
+ * @see #setHomeAsUpIndicator(android.graphics.drawable.Drawable)
+ */
+ public void setHomeActionContentDescription(int resId) { }
+
+ /**
* Listener interface for ActionBar navigation events.
*/
public interface OnNavigationListener {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ae0671b..68a2397 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -86,6 +86,7 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.renderscript.RenderScript;
+import android.security.AndroidKeyStoreProvider;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
@@ -101,6 +102,7 @@
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.net.InetAddress;
+import java.security.Security;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -5068,6 +5070,8 @@
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
+ Security.addProvider(new AndroidKeyStoreProvider());
+
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 3d9b2ae..92ec3ad 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -17,12 +17,12 @@
package android.app;
-import android.app.INotificationListener;
import android.app.ITransientNotification;
+import android.service.notification.StatusBarNotification;
import android.app.Notification;
+import android.content.ComponentName;
import android.content.Intent;
-
-import com.android.internal.statusbar.StatusBarNotification;
+import android.service.notification.INotificationListener;
/** {@hide} */
interface INotificationManager
@@ -41,7 +41,9 @@
StatusBarNotification[] getActiveNotifications(String callingPkg);
StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);
- void registerListener(in INotificationListener listener, String pkg, int userid);
+ void registerListener(in INotificationListener listener, in ComponentName component, int userid);
void unregisterListener(in INotificationListener listener, int userid);
-}
+ void clearNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
+ void clearAllNotificationsFromListener(in INotificationListener token);
+}
\ No newline at end of file
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ebca041..a7543a8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1603,7 +1603,7 @@
n.defaults = mDefaults;
n.flags = mFlags;
n.bigContentView = makeBigContentView();
- if (mLedOnMs != 0 && mLedOffMs != 0) {
+ if (mLedOnMs != 0 || mLedOffMs != 0) {
n.flags |= FLAG_SHOW_LIGHTS;
}
if ((mDefaults & DEFAULT_LIGHTS) != 0) {
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 16b4835..e9e7551 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -152,7 +152,15 @@
* not return until the current process is exiting.
*/
public static final native void joinThreadPool();
-
+
+ /**
+ * Returns true if the specified interface is a proxy.
+ * @hide
+ */
+ public static final boolean isProxy(IInterface iface) {
+ return iface.asBinder() != iface;
+ }
+
/**
* Default constructor initializes the object.
*/
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 66083c8..367d576 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -3796,50 +3796,11 @@
* Columns in the Data_Usage_Stat table
*/
protected interface DataUsageStatColumns {
- /** What the referenced {@link Data} was used for.
- * @see DataUsageStatColumns#USAGE_TYPE_CALL
- * @see DataUsageStatColumns#USAGE_TYPE_LONG_TEXT
- * @see DataUsageStatColumns#USAGE_TYPE_SHORT_TEXT
- */
- public static final String USAGE_TYPE = "usage_type";
-
/** The last time (in milliseconds) this {@link Data} was used. */
public static final String LAST_TIME_USED = "last_time_used";
- /** The number of times the referenced {@link Data} has been used for the purpose described
- * in {@link DataUsageStatColumns#USAGE_TYPE}.
- */
+ /** The number of times the referenced {@link Data} has been used. */
public static final String TIMES_USED = "times_used";
-
- /**
- * Integer value for USAGE_TYPE.
- * This type of usage refers to voice interaction, which includes phone calls, voice chat,
- * and video chat.
- *
- * @see DataUsageFeedback#USAGE_TYPE
- * @see DataUsageStatColumns#USAGE_TYPE
- */
- public static final int USAGE_TYPE_CALL = 0;
-
- /**
- * Integer value for USAGE_TYPE.
- * This type of usage refers to text interaction involving longer messages, which includes
- * email.
- *
- * @see DataUsageFeedback#USAGE_TYPE
- * @see DataUsageStatColumns#USAGE_TYPE
- */
- public static final int USAGE_TYPE_LONG_TEXT = 1;
-
- /**
- * Integer value for USAGE_TYPE.
- * This type of usage for text interaction involving shorter messages, which includes SMS
- * and text chat with email addresses.
- *
- * @see DataUsageFeedback#USAGE_TYPE
- * @see DataUsageStatColumns#USAGE_TYPE
- */
- public static final int USAGE_TYPE_SHORT_TEXT = 2;
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a0473a4..88ee414 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -655,6 +655,22 @@
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS";
+ /**
+ * Activity Action: Show Notification listener settings.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ * @see android.service.notification.NotificationListenerService
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_NOTIFICATION_LISTENER_SETTINGS
+ = "android.settings.NOTIFICATION_LISTENER_SETTINGS";
+
// End of Intent actions for Settings
/**
diff --git a/core/java/android/app/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
similarity index 89%
rename from core/java/android/app/INotificationListener.aidl
rename to core/java/android/service/notification/INotificationListener.aidl
index f010a2a..425fdc1 100644
--- a/core/java/android/app/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.app;
+package android.service.notification;
-import com.android.internal.statusbar.StatusBarNotification;
+import android.service.notification.StatusBarNotification;
/** @hide */
oneway interface INotificationListener
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
new file mode 100644
index 0000000..86bab2a
--- /dev/null
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -0,0 +1,138 @@
+/*
+ * 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 android.service.notification;
+
+import android.annotation.SdkConstant;
+import android.app.INotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+
+public abstract class NotificationListenerService extends Service {
+ // TAG = "NotificationListenerService[MySubclass]"
+ private final String TAG = NotificationListenerService.class.getSimpleName()
+ + "[" + getClass().getSimpleName() + "]";
+
+ private INotificationListenerWrapper mWrapper = null;
+
+ private INotificationManager mNoMan;
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE
+ = "android.service.notification.NotificationListenerService";
+
+ /**
+ * Implement this method to learn about new notifications as they are posted by apps.
+ *
+ * @param sbn A data structure encapsulating the original {@link android.app.Notification}
+ * object as well as its identifying information (tag and id) and source
+ * (package name).
+ */
+ public abstract void onNotificationPosted(StatusBarNotification sbn);
+
+ /**
+ * Implement this method to learn when notifications are removed.
+ * <P>
+ * This might occur because the user has dismissed the notification using system UI (or another
+ * notification listener) or because the app has withdrawn the notification.
+ *
+ * @param sbn A data structure encapsulating the original {@link android.app.Notification}
+ * object as well as its identifying information (tag and id) and source
+ * (package name).
+ */
+ public abstract void onNotificationRemoved(StatusBarNotification sbn);
+
+ private final INotificationManager getNotificationInterface() {
+ if (mNoMan == null) {
+ mNoMan = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ }
+ return mNoMan;
+ }
+
+ /**
+ * Inform the notification manager about dismissal of a single notification.
+ * <p>
+ * Use this if your listener has a user interface that allows the user to dismiss individual
+ * notifications, similar to the behavior of Android's status bar and notification panel.
+ * It should be called after the user dismisses a single notification using your UI;
+ * upon being informed, the notification manager will actually remove the notification
+ * and you will get an {@link #onNotificationRemoved(StatusBarNotification)} callback.
+ * <P>
+ * <b>Note:</b> If your listener allows the user to fire a notification's
+ * {@link android.app.Notification#contentIntent} by tapping/clicking/etc., you should call
+ * this method at that time <i>if</i> the Notification in question has the
+ * {@link android.app.Notification#FLAG_AUTO_CANCEL} flag set.
+ *
+ * @param pkg Package of the notifying app.
+ * @param tag Tag of the notification as specified by the notifying app in
+ * {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
+ * @param id ID of the notification as specified by the notifying app in
+ * {@link android.app.NotificationManager#notify(String, int, android.app.Notification)}.
+ */
+ public final void clearNotification(String pkg, String tag, int id) {
+ try {
+ getNotificationInterface().clearNotificationFromListener(mWrapper, pkg, tag, id);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
+
+ /**
+ * Inform the notification manager about dismissal of all notifications.
+ * <p>
+ * Use this if your listener has a user interface that allows the user to dismiss all
+ * notifications, similar to the behavior of Android's status bar and notification panel.
+ * It should be called after the user invokes the "dismiss all" function of your UI;
+ * upon being informed, the notification manager will actually remove all active notifications
+ * and you will get multiple {@link #onNotificationRemoved(StatusBarNotification)} callbacks.
+ *
+ * {@see #clearNotification(String, String, int)}
+ */
+ public final void clearAllNotifications() {
+ try {
+ getNotificationInterface().clearAllNotificationsFromListener(mWrapper);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (mWrapper == null) {
+ mWrapper = new INotificationListenerWrapper();
+ }
+ return mWrapper;
+ }
+
+ private class INotificationListenerWrapper extends INotificationListener.Stub {
+ @Override
+ public void onNotificationPosted(StatusBarNotification sbn) {
+ NotificationListenerService.this.onNotificationPosted(sbn);
+ }
+ @Override
+ public void onNotificationRemoved(StatusBarNotification sbn) {
+ NotificationListenerService.this.onNotificationRemoved(sbn);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.aidl b/core/java/android/service/notification/StatusBarNotification.aidl
similarity index 93%
rename from core/java/com/android/internal/statusbar/StatusBarNotification.aidl
rename to core/java/android/service/notification/StatusBarNotification.aidl
index bd9e89c..ba81972 100644
--- a/core/java/com/android/internal/statusbar/StatusBarNotification.aidl
+++ b/core/java/android/service/notification/StatusBarNotification.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.statusbar;
+package android.service.notification;
parcelable StatusBarNotification;
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
similarity index 80%
rename from core/java/com/android/internal/statusbar/StatusBarNotification.java
rename to core/java/android/service/notification/StatusBarNotification.java
index 23e87fc..ef5f8c4 100644
--- a/core/java/com/android/internal/statusbar/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.statusbar;
+package android.service.notification;
import android.app.Notification;
import android.os.Parcel;
@@ -23,34 +23,54 @@
/**
* Class encapsulating a Notification. Sent by the NotificationManagerService to clients including
- * the IStatusBar (in System UI).
+ * the status bar and any {@link android.service.notification.NotificationListenerService}s.
*/
public class StatusBarNotification implements Parcelable {
+ /** The package of the app that posted the notification. */
public final String pkg;
- public final String basePkg;
+ /** The id supplied to {@link android.app.NotificationManager#notify}. */
public final int id;
+ /** The tag supplied to {@link android.app.NotificationManager#notify}, or null if no tag
+ * was specified. */
public final String tag;
+
+ /** The notifying app's calling uid. @hide */
public final int uid;
+ /** The notifying app's base package. @hide */
+ public final String basePkg;
+ /** @hide */
public final int initialPid;
// TODO: make this field private and move callers to an accessor that
// ensures sourceUser is applied.
+
+ /** The {@link android.app.Notification} supplied to
+ * {@link android.app.NotificationManager#notify}. */
public final Notification notification;
- public final int score;
+ /** The {@link android.os.UserHandle} for whom this notification is intended. */
public final UserHandle user;
+ /** The time (in {@link System#currentTimeMillis} time) the notification was posted,
+ * which may be different than {@link android.app.Notification#when}.
+ */
public final long postTime;
- /** This is temporarily needed for the JB MR1 PDK. */
+ /** @hide */
+ public final int score;
+
+ /** This is temporarily needed for the JB MR1 PDK.
+ * @hide */
@Deprecated
public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score,
Notification notification) {
this(pkg, id, tag, uid, initialPid, score, notification, UserHandle.OWNER);
}
+ /** @hide */
public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score,
Notification notification, UserHandle user) {
this(pkg, null, id, tag, uid, initialPid, score, notification, user);
}
+ /** @hide */
public StatusBarNotification(String pkg, String basePkg, int id, String tag, int uid,
int initialPid, int score, Notification notification, UserHandle user) {
this(pkg, basePkg, id, tag, uid, initialPid, score, notification, user,
@@ -147,10 +167,17 @@
this.score, this.notification);
}
+ /** Convenience method to check the notification's flags for
+ * {@link Notification#FLAG_ONGOING_EVENT}.
+ */
public boolean isOngoing() {
return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
}
+ /** Convenience method to check the notification's flags for
+ * either {@link Notification#FLAG_ONGOING_EVENT} or
+ * {@link Notification#FLAG_NO_CLEAR}.
+ */
public boolean isClearable() {
return ((notification.flags & Notification.FLAG_ONGOING_EVENT) == 0)
&& ((notification.flags & Notification.FLAG_NO_CLEAR) == 0);
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
index a797176..40ee1ad 100644
--- a/core/java/android/view/InputChannel.java
+++ b/core/java/android/view/InputChannel.java
@@ -54,6 +54,7 @@
private native void nativeTransferTo(InputChannel other);
private native void nativeReadFromParcel(Parcel parcel);
private native void nativeWriteToParcel(Parcel parcel);
+ private native void nativeDup(InputChannel target);
private native String nativeGetName();
@@ -64,7 +65,7 @@
*/
public InputChannel() {
}
-
+
@Override
protected void finalize() throws Throwable {
try {
@@ -125,6 +126,15 @@
nativeTransferTo(outParameter);
}
+ /**
+ * Duplicates the input channel.
+ */
+ public InputChannel dup() {
+ InputChannel target = new InputChannel();
+ nativeDup(target);
+ return target;
+ }
+
@Override
public int describeContents() {
return Parcelable.CONTENTS_FILE_DESCRIPTOR;
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index dd523d2..2595ee5 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -371,8 +371,8 @@
if (axis < 0) {
break;
}
- addMotionRange(axis, in.readInt(),
- in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
+ addMotionRange(axis, in.readInt(), in.readFloat(), in.readFloat(), in.readFloat(),
+ in.readFloat(), in.readFloat());
}
}
@@ -584,8 +584,8 @@
// Called from native code.
private void addMotionRange(int axis, int source,
- float min, float max, float flat, float fuzz) {
- mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz));
+ float min, float max, float flat, float fuzz, float resolution) {
+ mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution));
}
/**
@@ -625,14 +625,17 @@
private float mMax;
private float mFlat;
private float mFuzz;
+ private float mResolution;
- private MotionRange(int axis, int source, float min, float max, float flat, float fuzz) {
+ private MotionRange(int axis, int source, float min, float max, float flat, float fuzz,
+ float resolution) {
mAxis = axis;
mSource = source;
mMin = min;
mMax = max;
mFlat = flat;
mFuzz = fuzz;
+ mResolution = resolution;
}
/**
@@ -711,6 +714,14 @@
public float getFuzz() {
return mFuzz;
}
+
+ /**
+ * Gets the resolution for input device measurements with respect to this axis.
+ * @return The resolution in units per millimeter, or units per radian for rotational axes.
+ */
+ public float getResolution() {
+ return mResolution;
+ }
}
@Override
@@ -734,6 +745,7 @@
out.writeFloat(range.mMax);
out.writeFloat(range.mFlat);
out.writeFloat(range.mFuzz);
+ out.writeFloat(range.mResolution);
}
out.writeInt(-1);
}
@@ -788,6 +800,7 @@
description.append(" max=").append(range.mMax);
description.append(" flat=").append(range.mFlat);
description.append(" fuzz=").append(range.mFuzz);
+ description.append(" resolution=").append(range.mResolution);
description.append("\n");
}
return description.toString();
diff --git a/core/java/android/view/Overlay.java b/core/java/android/view/Overlay.java
deleted file mode 100644
index 6630752..0000000
--- a/core/java/android/view/Overlay.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 android.view;
-
-import android.graphics.drawable.Drawable;
-
-/**
- * An overlay is an extra layer that sits on top of a View (the "host view")
- * which is drawn after all other content in that view (including children,
- * if the view is a ViewGroup). Interaction with the overlay layer is done in
- * terms of adding/removing views and drawables.
- *
- * @see android.view.View#getOverlay()
- */
-public interface Overlay {
-
- /**
- * Adds a Drawable to the overlay. The bounds of the drawable should be relative to
- * the host view. Any drawable added to the overlay should be removed when it is no longer
- * needed or no longer visible.
- *
- * @param drawable The Drawable to be added to the overlay. This drawable will be
- * drawn when the view redraws its overlay.
- * @see #remove(android.graphics.drawable.Drawable)
- * @see #add(View)
- */
- void add(Drawable drawable);
-
- /**
- * Removes the specified Drawable from the overlay.
- *
- * @param drawable The Drawable to be removed from the overlay.
- * @see #add(android.graphics.drawable.Drawable)
- */
- void remove(Drawable drawable);
-
- /**
- * Adds a View to the overlay. The bounds of the added view should be
- * relative to the host view. Any view added to the overlay should be
- * removed when it is no longer needed or no longer visible.
- *
- * <p>If the view has a parent, the view will be removed from that parent
- * before being added to the overlay. Also, the view will be repositioned
- * such that it is in the same relative location inside the activity. For
- * example, if the view's current parent lies 100 pixels to the right
- * and 200 pixels down from the origin of the overlay's
- * host view, then the view will be offset by (100, 200).</p>
- *
- * @param view The View to be added to the overlay. The added view will be
- * drawn when the overlay is drawn.
- * @see #remove(View)
- * @see #add(android.graphics.drawable.Drawable)
- */
- void add(View view);
-
- /**
- * Removes the specified View from the overlay.
- *
- * @param view The View to be removed from the overlay.
- * @see #add(View)
- */
- void remove(View view);
-
- /**
- * Removes all views and drawables from the overlay.
- */
- void clear();
-}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3b06da7..a520e17 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12107,7 +12107,7 @@
//System.out.println("Attached! " + this);
mAttachInfo = info;
if (mOverlay != null) {
- mOverlay.dispatchAttachedToWindow(info, visibility);
+ mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
}
mWindowAttachCount++;
// We will need to evaluate the drawable state at least once.
@@ -12178,7 +12178,7 @@
mAttachInfo = null;
if (mOverlay != null) {
- mOverlay.dispatchDetachedFromWindow();
+ mOverlay.getOverlayView().dispatchDetachedFromWindow();
}
}
@@ -12831,7 +12831,7 @@
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
dispatchDraw(canvas);
if (mOverlay != null && !mOverlay.isEmpty()) {
- mOverlay.draw(canvas);
+ mOverlay.getOverlayView().draw(canvas);
}
} else {
draw(canvas);
@@ -13147,7 +13147,7 @@
mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchDraw(canvas);
if (mOverlay != null && !mOverlay.isEmpty()) {
- mOverlay.draw(canvas);
+ mOverlay.getOverlayView().draw(canvas);
}
} else {
draw(canvas);
@@ -13905,7 +13905,7 @@
onDrawScrollBars(canvas);
if (mOverlay != null && !mOverlay.isEmpty()) {
- mOverlay.dispatchDraw(canvas);
+ mOverlay.getOverlayView().dispatchDraw(canvas);
}
// we're done...
@@ -14049,34 +14049,24 @@
onDrawScrollBars(canvas);
if (mOverlay != null && !mOverlay.isEmpty()) {
- mOverlay.dispatchDraw(canvas);
+ mOverlay.getOverlayView().dispatchDraw(canvas);
}
}
/**
- * Called by the addToOverlay() methods to create, attach, and size the overlay as necessary
+ * Returns the overlay for this view, creating it if it does not yet exist.
+ * Adding drawables to the overlay will cause them to be displayed whenever
+ * the view itself is redrawn. Objects in the overlay should be actively
+ * managed: remove them when they should not be displayed anymore. The
+ * overlay will always have the same size as its host view.
+ *
+ * @return The ViewOverlay object for this view.
+ * @see ViewOverlay
*/
- private void setupOverlay() {
+ public ViewOverlay getOverlay() {
if (mOverlay == null) {
mOverlay = new ViewOverlay(mContext, this);
- mOverlay.mAttachInfo = mAttachInfo;
- mOverlay.setRight(mRight);
- mOverlay.setBottom(mBottom);
}
- }
-
- /**
- * Returns the overlay for this view, creating it if it does not yet exist. Adding drawables
- * and/or views to the overlay will cause them to be displayed whenever the view itself is
- * redrawn. Objects in the overlay should be actively managed: remove them when they should
- * not be displayed anymore and invalidate this view appropriately when overlay drawables
- * change. The overlay will always have the same size as its host view.
- *
- * @return The Overlay object for this view.
- * @see Overlay
- */
- public Overlay getOverlay() {
- setupOverlay();
return mOverlay;
}
@@ -14360,8 +14350,8 @@
private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) {
onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
if (mOverlay != null) {
- mOverlay.setRight(mRight);
- mOverlay.setBottom(mBottom);
+ mOverlay.getOverlayView().setRight(newWidth);
+ mOverlay.getOverlayView().setBottom(newHeight);
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f615e1bc..c07191a 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1876,34 +1876,10 @@
// have become out of sync.
removePointersFromTouchTargets(idBitsToAssign);
- final float x = ev.getX(actionIndex);
- final float y = ev.getY(actionIndex);
-
- if (mOverlay != null) {
- ViewOverlay overlay = (ViewOverlay) mOverlay;
- // Check to see whether the overlay can handle the event
- final View child = mOverlay;
- if (canViewReceivePointerEvents(child) &&
- isTransformedTouchPointInView(x, y, child, null)) {
- newTouchTarget = getTouchTarget(child);
- if (newTouchTarget != null) {
- newTouchTarget.pointerIdBits |= idBitsToAssign;
- } else {
- resetCancelNextUpFlag(child);
- if (dispatchTransformedTouchEvent(ev, false, child,
- idBitsToAssign)) {
- mLastTouchDownTime = ev.getDownTime();
- mLastTouchDownX = ev.getX();
- mLastTouchDownY = ev.getY();
- newTouchTarget = addTouchTarget(child, idBitsToAssign);
- alreadyDispatchedToNewTouchTarget = true;
- }
- }
- }
- }
-
final int childrenCount = mChildrenCount;
if (newTouchTarget == null && childrenCount != 0) {
+ final float x = ev.getX(actionIndex);
+ final float y = ev.getY(actionIndex);
// Find a child that can receive the event.
// Scan children from front to back.
final View[] children = mChildren;
@@ -2991,6 +2967,26 @@
}
/**
+ * Returns the ViewGroupOverlay for this view group, creating it if it does
+ * not yet exist. In addition to {@link ViewOverlay}'s support for drawables,
+ * {@link ViewGroupOverlay} allows views to be added to the overlay. These
+ * views, like overlay drawables, are visual-only; they do not receive input
+ * events and should not be used as anything other than a temporary
+ * representation of a view in a parent container, such as might be used
+ * by an animation effect.
+ *
+ * @return The ViewGroupOverlay object for this view.
+ * @see ViewGroupOverlay
+ */
+ @Override
+ public ViewGroupOverlay getOverlay() {
+ if (mOverlay == null) {
+ mOverlay = new ViewGroupOverlay(mContext, this);
+ }
+ return (ViewGroupOverlay) mOverlay;
+ }
+
+ /**
* Returns the index of the child to draw for this iteration. Override this
* if you want to change the drawing order of children. By default, it
* returns i.
@@ -3055,11 +3051,12 @@
}
}
if (mOverlay != null) {
- mOverlay.mRecreateDisplayList = (mOverlay.mPrivateFlags & PFLAG_INVALIDATED)
+ View overlayView = mOverlay.getOverlayView();
+ overlayView.mRecreateDisplayList = (overlayView.mPrivateFlags & PFLAG_INVALIDATED)
== PFLAG_INVALIDATED;
- mOverlay.mPrivateFlags &= ~PFLAG_INVALIDATED;
- mOverlay.getDisplayList();
- mOverlay.mRecreateDisplayList = false;
+ overlayView.mPrivateFlags &= ~PFLAG_INVALIDATED;
+ overlayView.getDisplayList();
+ overlayView.mRecreateDisplayList = false;
}
}
diff --git a/core/java/android/view/ViewGroupOverlay.java b/core/java/android/view/ViewGroupOverlay.java
new file mode 100644
index 0000000..c1b24f2
--- /dev/null
+++ b/core/java/android/view/ViewGroupOverlay.java
@@ -0,0 +1,75 @@
+/*
+ * 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 android.view;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+/**
+ * A group overlay is an extra layer that sits on top of a ViewGroup
+ * (the "host view") which is drawn after all other content in that view
+ * (including the view group's children). Interaction with the overlay
+ * layer is done by adding and removing views and drawables.
+ *
+ * <p>ViewGroupOverlay is a subclass of {@link ViewOverlay}, adding the ability to
+ * manage views for overlays on ViewGroups, in addition to the drawable
+ * support in ViewOverlay.</p>
+ *
+ * @see ViewGroup#getOverlay()
+ */
+public class ViewGroupOverlay extends ViewOverlay {
+
+ ViewGroupOverlay(Context context, View hostView) {
+ super(context, hostView);
+ }
+
+ /**
+ * Adds a View to the overlay. The bounds of the added view should be
+ * relative to the host view. Any view added to the overlay should be
+ * removed when it is no longer needed or no longer visible.
+ *
+ * <p>Views in the overlay are visual-only; they do not receive input
+ * events and do not participate in focus traversal. Overlay views
+ * are intended to be transient, such as might be needed by a temporary
+ * animation effect.</p>
+ *
+ * <p>If the view has a parent, the view will be removed from that parent
+ * before being added to the overlay. Also, the view will be repositioned
+ * such that it is in the same relative location inside the activity. For
+ * example, if the view's current parent lies 100 pixels to the right
+ * and 200 pixels down from the origin of the overlay's
+ * host view, then the view will be offset by (100, 200).</p>
+ *
+ * @param view The View to be added to the overlay. The added view will be
+ * drawn when the overlay is drawn.
+ * @see #remove(View)
+ * @see ViewOverlay#add(Drawable)
+ */
+ public void add(View view) {
+ mOverlayViewGroup.add(view);
+ }
+
+ /**
+ * Removes the specified View from the overlay.
+ *
+ * @param view The View to be removed from the overlay.
+ * @see #add(View)
+ * @see ViewOverlay#remove(Drawable)
+ */
+ public void remove(View view) {
+ mOverlayViewGroup.remove(view);
+ }
+}
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 8b18d53..78e2597 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -23,215 +23,286 @@
import java.util.ArrayList;
/**
- * ViewOverlay is a container that View uses to host all objects (views and
- * drawables) that are added to its "overlay", gotten through
- * {@link View#getOverlay()}. Views and drawables are added to the overlay
- * via the add/remove methods in this class. These views and drawables are
- * drawn whenever the view itself is drawn; first the view draws its own
- * content (and children, if it is a ViewGroup), then it draws its overlay
- * (if it has one).
+ * An overlay is an extra layer that sits on top of a View (the "host view")
+ * which is drawn after all other content in that view (including children,
+ * if the view is a ViewGroup). Interaction with the overlay layer is done
+ * by adding and removing drawables.
*
- * Besides managing and drawing the list of drawables, this class serves
- * two purposes:
- * (1) it noops layout calls because children are absolutely positioned and
- * (2) it forwards all invalidation calls to its host view. The invalidation
- * redirect is necessary because the overlay is not a child of the host view
- * and invalidation cannot therefore follow the normal path up through the
- * parent hierarchy.
+ * <p>An overlay requested from a ViewGroup is of type {@link ViewGroupOverlay},
+ * which also supports adding and removing views.</p>
*
- * @hide
+ * @see View#getOverlay() View.getOverlay()
+ * @see ViewGroup#getOverlay() ViewGroup.getOverlay()
+ * @see ViewGroupOverlay
*/
-class ViewOverlay extends ViewGroup implements Overlay {
+public class ViewOverlay {
/**
- * The View for which this is an overlay. Invalidations of the overlay are redirected to
- * this host view.
+ * The actual container for the drawables (and views, if it's a ViewGroupOverlay).
+ * All of the management and rendering details for the overlay are handled in
+ * OverlayViewGroup.
*/
- View mHostView;
+ OverlayViewGroup mOverlayViewGroup;
- /**
- * The set of drawables to draw when the overlay is rendered.
- */
- ArrayList<Drawable> mDrawables = null;
-
- ViewOverlay(Context context, View host) {
- super(context);
- mHostView = host;
- mParent = mHostView.getParent();
+ ViewOverlay(Context context, View hostView) {
+ mOverlayViewGroup = new OverlayViewGroup(context, hostView);
}
- @Override
+ /**
+ * Used internally by View and ViewGroup to handle drawing and invalidation
+ * of the overlay
+ * @return
+ */
+ ViewGroup getOverlayView() {
+ return mOverlayViewGroup;
+ }
+
+ /**
+ * Adds a Drawable to the overlay. The bounds of the drawable should be relative to
+ * the host view. Any drawable added to the overlay should be removed when it is no longer
+ * needed or no longer visible.
+ *
+ * @param drawable The Drawable to be added to the overlay. This drawable will be
+ * drawn when the view redraws its overlay.
+ * @see #remove(Drawable)
+ */
public void add(Drawable drawable) {
- if (mDrawables == null) {
- mDrawables = new ArrayList<Drawable>();
- }
- if (!mDrawables.contains(drawable)) {
- // Make each drawable unique in the overlay; can't add it more than once
- mDrawables.add(drawable);
- invalidate(drawable.getBounds());
- drawable.setCallback(this);
- }
+ mOverlayViewGroup.add(drawable);
}
- @Override
+ /**
+ * Removes the specified Drawable from the overlay.
+ *
+ * @param drawable The Drawable to be removed from the overlay.
+ * @see #add(Drawable)
+ */
public void remove(Drawable drawable) {
- if (mDrawables != null) {
- mDrawables.remove(drawable);
- invalidate(drawable.getBounds());
- drawable.setCallback(null);
- }
+ mOverlayViewGroup.remove(drawable);
}
- @Override
- public void invalidateDrawable(Drawable drawable) {
- invalidate(drawable.getBounds());
- }
-
- @Override
- public void add(View child) {
- int deltaX = 0;
- int deltaY = 0;
- if (child.getParent() instanceof ViewGroup) {
- ViewGroup parent = (ViewGroup) child.getParent();
- if (parent != mHostView) {
- // Moving to different container; figure out how to position child such that
- // it is in the same location on the screen
- int[] parentLocation = new int[2];
- int[] hostViewLocation = new int[2];
- parent.getLocationOnScreen(parentLocation);
- mHostView.getLocationOnScreen(hostViewLocation);
- child.offsetLeftAndRight(parentLocation[0] - hostViewLocation[0]);
- child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
- }
- parent.removeView(child);
- }
- super.addView(child);
- }
-
- @Override
- public void remove(View view) {
- super.removeView(view);
- }
-
- @Override
+ /**
+ * Removes all content from the overlay.
+ */
public void clear() {
- removeAllViews();
- mDrawables.clear();
+ mOverlayViewGroup.clear();
}
boolean isEmpty() {
- if (getChildCount() == 0 && (mDrawables == null || mDrawables.size() == 0)) {
- return true;
- }
- return false;
+ return mOverlayViewGroup.isEmpty();
}
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
- final int numDrawables = (mDrawables == null) ? 0 : mDrawables.size();
- for (int i = 0; i < numDrawables; ++i) {
- mDrawables.get(i).draw(canvas);
- }
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- // Noop: children are positioned absolutely
- }
-
- /*
- The following invalidation overrides exist for the purpose of redirecting invalidation to
- the host view. The overlay is not parented to the host view (since a View cannot be a parent),
- so the invalidation cannot proceed through the normal parent hierarchy.
- There is a built-in assumption that the overlay exactly covers the host view, therefore
- the invalidation rectangles received do not need to be adjusted when forwarded to
- the host view.
+ /**
+ * OverlayViewGroup is a container that View and ViewGroup use to host
+ * drawables and views added to their overlays ({@link ViewOverlay} and
+ * {@link ViewGroupOverlay}, respectively). Drawables are added to the overlay
+ * via the add/remove methods in ViewOverlay, Views are added/removed via
+ * ViewGroupOverlay. These drawable and view objects are
+ * drawn whenever the view itself is drawn; first the view draws its own
+ * content (and children, if it is a ViewGroup), then it draws its overlay
+ * (if it has one).
+ *
+ * <p>Besides managing and drawing the list of drawables, this class serves
+ * two purposes:
+ * (1) it noops layout calls because children are absolutely positioned and
+ * (2) it forwards all invalidation calls to its host view. The invalidation
+ * redirect is necessary because the overlay is not a child of the host view
+ * and invalidation cannot therefore follow the normal path up through the
+ * parent hierarchy.</p>
+ *
+ * @see View#getOverlay()
+ * @see ViewGroup#getOverlay()
*/
+ static class OverlayViewGroup extends ViewGroup {
- @Override
- public void invalidate(Rect dirty) {
- super.invalidate(dirty);
- if (mHostView != null) {
- mHostView.invalidate(dirty);
+ /**
+ * The View for which this is an overlay. Invalidations of the overlay are redirected to
+ * this host view.
+ */
+ View mHostView;
+
+ /**
+ * The set of drawables to draw when the overlay is rendered.
+ */
+ ArrayList<Drawable> mDrawables = null;
+
+ OverlayViewGroup(Context context, View hostView) {
+ super(context);
+ mHostView = hostView;
+ mAttachInfo = mHostView.mAttachInfo;
+ mRight = hostView.getWidth();
+ mBottom = hostView.getHeight();
}
- }
- @Override
- public void invalidate(int l, int t, int r, int b) {
- super.invalidate(l, t, r, b);
- if (mHostView != null) {
- mHostView.invalidate(l, t, r, b);
- }
- }
+ public void add(Drawable drawable) {
+ if (mDrawables == null) {
- @Override
- public void invalidate() {
- super.invalidate();
- if (mHostView != null) {
- mHostView.invalidate();
- }
- }
-
- @Override
- void invalidate(boolean invalidateCache) {
- super.invalidate(invalidateCache);
- if (mHostView != null) {
- mHostView.invalidate(invalidateCache);
- }
- }
-
- @Override
- void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
- super.invalidateViewProperty(invalidateParent, forceRedraw);
- if (mHostView != null) {
- mHostView.invalidateViewProperty(invalidateParent, forceRedraw);
- }
- }
-
- @Override
- protected void invalidateParentCaches() {
- super.invalidateParentCaches();
- if (mHostView != null) {
- mHostView.invalidateParentCaches();
- }
- }
-
- @Override
- protected void invalidateParentIfNeeded() {
- super.invalidateParentIfNeeded();
- if (mHostView != null) {
- mHostView.invalidateParentIfNeeded();
- }
- }
-
- public void invalidateChildFast(View child, final Rect dirty) {
- if (mHostView != null) {
- // Note: This is not a "fast" invalidation. Would be nice to instead invalidate using DL
- // properties and a dirty rect instead of causing a real invalidation of the host view
- int left = child.mLeft;
- int top = child.mTop;
- if (!child.getMatrix().isIdentity()) {
- child.transformRect(dirty);
+ mDrawables = new ArrayList<Drawable>();
}
- dirty.offset(left, top);
- mHostView.invalidate(dirty);
- }
- }
-
- @Override
- public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
- if (mHostView != null) {
- dirty.offset(location[0], location[1]);
- if (mHostView instanceof ViewGroup) {
- location[0] = 0;
- location[1] = 0;
- super.invalidateChildInParent(location, dirty);
- return ((ViewGroup) mHostView).invalidateChildInParent(location, dirty);
- } else {
- invalidate(dirty);
+ if (!mDrawables.contains(drawable)) {
+ // Make each drawable unique in the overlay; can't add it more than once
+ mDrawables.add(drawable);
+ invalidate(drawable.getBounds());
+ drawable.setCallback(this);
}
}
- return null;
+
+ public void remove(Drawable drawable) {
+ if (mDrawables != null) {
+ mDrawables.remove(drawable);
+ invalidate(drawable.getBounds());
+ drawable.setCallback(null);
+ }
+ }
+
+ public void add(View child) {
+ if (child.getParent() instanceof ViewGroup) {
+ ViewGroup parent = (ViewGroup) child.getParent();
+ if (parent != mHostView) {
+ // Moving to different container; figure out how to position child such that
+ // it is in the same location on the screen
+ int[] parentLocation = new int[2];
+ int[] hostViewLocation = new int[2];
+ parent.getLocationOnScreen(parentLocation);
+ mHostView.getLocationOnScreen(hostViewLocation);
+ child.offsetLeftAndRight(parentLocation[0] - hostViewLocation[0]);
+ child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
+ }
+ parent.removeView(child);
+ }
+ super.addView(child);
+ }
+
+ public void remove(View view) {
+ super.removeView(view);
+ }
+
+ public void clear() {
+ removeAllViews();
+ mDrawables.clear();
+ }
+
+ boolean isEmpty() {
+ if (getChildCount() == 0 &&
+ (mDrawables == null || mDrawables.size() == 0)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void invalidateDrawable(Drawable drawable) {
+ invalidate(drawable.getBounds());
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ final int numDrawables = (mDrawables == null) ? 0 : mDrawables.size();
+ for (int i = 0; i < numDrawables; ++i) {
+ mDrawables.get(i).draw(canvas);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ // Noop: children are positioned absolutely
+ }
+
+ /*
+ The following invalidation overrides exist for the purpose of redirecting invalidation to
+ the host view. The overlay is not parented to the host view (since a View cannot be a
+ parent), so the invalidation cannot proceed through the normal parent hierarchy.
+ There is a built-in assumption that the overlay exactly covers the host view, therefore
+ the invalidation rectangles received do not need to be adjusted when forwarded to
+ the host view.
+ */
+
+ @Override
+ public void invalidate(Rect dirty) {
+ super.invalidate(dirty);
+ if (mHostView != null) {
+ mHostView.invalidate(dirty);
+ }
+ }
+
+ @Override
+ public void invalidate(int l, int t, int r, int b) {
+ super.invalidate(l, t, r, b);
+ if (mHostView != null) {
+ mHostView.invalidate(l, t, r, b);
+ }
+ }
+
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ if (mHostView != null) {
+ mHostView.invalidate();
+ }
+ }
+
+ @Override
+ void invalidate(boolean invalidateCache) {
+ super.invalidate(invalidateCache);
+ if (mHostView != null) {
+ mHostView.invalidate(invalidateCache);
+ }
+ }
+
+ @Override
+ void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
+ super.invalidateViewProperty(invalidateParent, forceRedraw);
+ if (mHostView != null) {
+ mHostView.invalidateViewProperty(invalidateParent, forceRedraw);
+ }
+ }
+
+ @Override
+ protected void invalidateParentCaches() {
+ super.invalidateParentCaches();
+ if (mHostView != null) {
+ mHostView.invalidateParentCaches();
+ }
+ }
+
+ @Override
+ protected void invalidateParentIfNeeded() {
+ super.invalidateParentIfNeeded();
+ if (mHostView != null) {
+ mHostView.invalidateParentIfNeeded();
+ }
+ }
+
+ public void invalidateChildFast(View child, final Rect dirty) {
+ if (mHostView != null) {
+ // Note: This is not a "fast" invalidation. Would be nice to instead invalidate
+ // using DisplayList properties and a dirty rect instead of causing a real
+ // invalidation of the host view
+ int left = child.mLeft;
+ int top = child.mTop;
+ if (!child.getMatrix().isIdentity()) {
+ child.transformRect(dirty);
+ }
+ dirty.offset(left, top);
+ mHostView.invalidate(dirty);
+ }
+ }
+
+ @Override
+ public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
+ if (mHostView != null) {
+ dirty.offset(location[0], location[1]);
+ if (mHostView instanceof ViewGroup) {
+ location[0] = 0;
+ location[1] = 0;
+ super.invalidateChildInParent(location, dirty);
+ return ((ViewGroup) mHostView).invalidateChildInParent(location, dirty);
+ } else {
+ invalidate(dirty);
+ }
+ }
+ return null;
+ }
}
+
}
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index 684ec07..17eb2df 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -84,6 +85,7 @@
// See http://www.whatwg.org/specs/web-apps/current-work/#event-media-timeupdate
private Timer mTimer;
private final class TimeupdateTask extends TimerTask {
+ @Override
public void run() {
HTML5Audio.this.obtainMessage(TIMEUPDATE).sendToTarget();
}
@@ -139,11 +141,13 @@
// (i.e. the webviewcore thread here)
// MediaPlayer.OnBufferingUpdateListener
+ @Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
nativeOnBuffering(percent, mNativePointer);
}
// MediaPlayer.OnCompletionListener;
+ @Override
public void onCompletion(MediaPlayer mp) {
mState = COMPLETE;
mProcessingOnEnd = true;
@@ -156,6 +160,7 @@
}
// MediaPlayer.OnErrorListener
+ @Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mState = ERROR;
resetMediaPlayer();
@@ -164,6 +169,7 @@
}
// MediaPlayer.OnPreparedListener
+ @Override
public void onPrepared(MediaPlayer mp) {
mState = PREPARED;
if (mTimer != null) {
@@ -178,6 +184,7 @@
}
// MediaPlayer.OnSeekCompleteListener
+ @Override
public void onSeekComplete(MediaPlayer mp) {
nativeOnTimeupdate(mp.getCurrentPosition(), mNativePointer);
}
@@ -231,7 +238,7 @@
headers.put(HIDE_URL_LOGS, "true");
}
- mMediaPlayer.setDataSource(url, headers);
+ mMediaPlayer.setDataSource(mContext, Uri.parse(url), headers);
mState = INITIALIZED;
mMediaPlayer.prepareAsync();
} catch (IOException e) {
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index b2073b1..34cfea5 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -20,6 +20,7 @@
import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -77,6 +78,7 @@
private final PermissionInfoComparator mPermComparator = new PermissionInfoComparator();
private final List<MyPermissionInfo> mPermsList = new ArrayList<MyPermissionInfo>();
private final CharSequence mNewPermPrefix;
+ private String mPackageName;
static class MyPermissionGroupInfo extends PermissionGroupInfo {
CharSequence mLabel;
@@ -138,6 +140,8 @@
MyPermissionGroupInfo mGroup;
MyPermissionInfo mPerm;
AlertDialog mDialog;
+ private boolean mShowRevokeUI = false;
+ private String mPackageName;
public PermissionItemView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -145,9 +149,12 @@
}
public void setPermission(MyPermissionGroupInfo grp, MyPermissionInfo perm,
- boolean first, CharSequence newPermPrefix) {
+ boolean first, CharSequence newPermPrefix, String packageName,
+ boolean showRevokeUI) {
mGroup = grp;
mPerm = perm;
+ mShowRevokeUI = showRevokeUI;
+ mPackageName = packageName;
ImageView permGrpIcon = (ImageView) findViewById(R.id.perm_icon);
TextView permNameView = (TextView) findViewById(R.id.perm_name);
@@ -206,6 +213,7 @@
}
builder.setCancelable(true);
builder.setIcon(mGroup.loadGroupIcon(pm));
+ addRevokeUIIfNecessary(builder);
mDialog = builder.show();
mDialog.setCanceledOnTouchOutside(true);
}
@@ -218,6 +226,30 @@
mDialog.dismiss();
}
}
+
+ private void addRevokeUIIfNecessary(AlertDialog.Builder builder) {
+ if (!mShowRevokeUI) {
+ return;
+ }
+
+ final boolean isRequired =
+ ((mPerm.mExistingReqFlags & PackageInfo.REQUESTED_PERMISSION_REQUIRED) != 0);
+
+ if (isRequired) {
+ return;
+ }
+
+ DialogInterface.OnClickListener ocl = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ PackageManager pm = getContext().getPackageManager();
+ pm.revokePermission(mPackageName, mPerm.name);
+ PermissionItemView.this.setVisibility(View.GONE);
+ }
+ };
+ builder.setNegativeButton(R.string.revoke, ocl);
+ builder.setPositiveButton(R.string.ok, null);
+ }
}
private AppSecurityPermissions(Context context) {
@@ -230,6 +262,7 @@
public AppSecurityPermissions(Context context, String packageName) {
this(context);
+ mPackageName = packageName;
Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
PackageInfo pkgInfo;
try {
@@ -252,6 +285,7 @@
if(info == null) {
return;
}
+ mPackageName = info.packageName;
// Convert to a PackageInfo
PackageInfo installedPkgInfo = null;
@@ -419,15 +453,23 @@
}
public View getPermissionsView() {
- return getPermissionsView(WHICH_ALL);
+ return getPermissionsView(WHICH_ALL, false);
+ }
+
+ public View getPermissionsViewWithRevokeButtons() {
+ return getPermissionsView(WHICH_ALL, true);
}
public View getPermissionsView(int which) {
+ return getPermissionsView(which, false);
+ }
+
+ private View getPermissionsView(int which, boolean showRevokeUI) {
LinearLayout permsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
LinearLayout displayList = (LinearLayout) permsView.findViewById(R.id.perms_list);
View noPermsView = permsView.findViewById(R.id.no_permissions);
- displayPermissions(mPermGroupsList, displayList, which);
+ displayPermissions(mPermGroupsList, displayList, which, showRevokeUI);
if (displayList.getChildCount() <= 0) {
noPermsView.setVisibility(View.VISIBLE);
}
@@ -440,7 +482,7 @@
* list of permission descriptions.
*/
private void displayPermissions(List<MyPermissionGroupInfo> groups,
- LinearLayout permListView, int which) {
+ LinearLayout permListView, int which, boolean showRevokeUI) {
permListView.removeAllViews();
int spacing = (int)(8*mContext.getResources().getDisplayMetrics().density);
@@ -451,7 +493,7 @@
for (int j=0; j<perms.size(); j++) {
MyPermissionInfo perm = perms.get(j);
View view = getPermissionItemView(grp, perm, j == 0,
- which != WHICH_NEW ? mNewPermPrefix : null);
+ which != WHICH_NEW ? mNewPermPrefix : null, showRevokeUI);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -470,18 +512,19 @@
}
private PermissionItemView getPermissionItemView(MyPermissionGroupInfo grp,
- MyPermissionInfo perm, boolean first, CharSequence newPermPrefix) {
- return getPermissionItemView(mContext, mInflater, grp, perm, first, newPermPrefix);
+ MyPermissionInfo perm, boolean first, CharSequence newPermPrefix, boolean showRevokeUI) {
+ return getPermissionItemView(mContext, mInflater, grp, perm, first, newPermPrefix,
+ mPackageName, showRevokeUI);
}
private static PermissionItemView getPermissionItemView(Context context, LayoutInflater inflater,
MyPermissionGroupInfo grp, MyPermissionInfo perm, boolean first,
- CharSequence newPermPrefix) {
- PermissionItemView permView = (PermissionItemView)inflater.inflate(
+ CharSequence newPermPrefix, String packageName, boolean showRevokeUI) {
+ PermissionItemView permView = (PermissionItemView)inflater.inflate(
(perm.flags & PermissionInfo.FLAG_COSTS_MONEY) != 0
? R.layout.app_permission_item_money : R.layout.app_permission_item,
null);
- permView.setPermission(grp, perm, first, newPermPrefix);
+ permView.setPermission(grp, perm, first, newPermPrefix, packageName, showRevokeUI);
return permView;
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 529de2e..3df7258 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -220,28 +220,29 @@
// with MeasureSpec value overflow and RelativeLayout was one source of them.
// Some apps came to rely on them. :(
private boolean mAllowBrokenMeasureSpecs = false;
+ // Compatibility hack. Old versions of the platform would not take
+ // margins and padding into account when generating the height measure spec
+ // for children during the horizontal measure pass.
+ private boolean mMeasureVerticalWithPaddingMargin = false;
// A default width used for RTL measure pass
- private static int DEFAULT_WIDTH = Integer.MAX_VALUE / 2;
+ private static final int DEFAULT_WIDTH = Integer.MAX_VALUE / 2;
public RelativeLayout(Context context) {
super(context);
- mAllowBrokenMeasureSpecs = context.getApplicationInfo().targetSdkVersion <=
- Build.VERSION_CODES.JELLY_BEAN_MR1;
+ queryCompatibilityModes(context);
}
public RelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initFromAttributes(context, attrs);
- mAllowBrokenMeasureSpecs = context.getApplicationInfo().targetSdkVersion <=
- Build.VERSION_CODES.JELLY_BEAN_MR1;
+ queryCompatibilityModes(context);
}
public RelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initFromAttributes(context, attrs);
- mAllowBrokenMeasureSpecs = context.getApplicationInfo().targetSdkVersion <=
- Build.VERSION_CODES.JELLY_BEAN_MR1;
+ queryCompatibilityModes(context);
}
private void initFromAttributes(Context context, AttributeSet attrs) {
@@ -251,6 +252,12 @@
a.recycle();
}
+ private void queryCompatibilityModes(Context context) {
+ int version = context.getApplicationInfo().targetSdkVersion;
+ mAllowBrokenMeasureSpecs = version <= Build.VERSION_CODES.JELLY_BEAN_MR1;
+ mMeasureVerticalWithPaddingMargin = version >= Build.VERSION_CODES.JELLY_BEAN_MR2;
+ }
+
@Override
public boolean shouldDelayChildPressedState() {
return false;
@@ -692,6 +699,11 @@
params.leftMargin, params.rightMargin,
mPaddingLeft, mPaddingRight,
myWidth);
+ int maxHeight = myHeight;
+ if (mMeasureVerticalWithPaddingMargin) {
+ maxHeight = Math.max(0, myHeight - mPaddingTop - mPaddingBottom -
+ params.topMargin - params.bottomMargin);
+ }
int childHeightMeasureSpec;
if (myHeight < 0 && !mAllowBrokenMeasureSpecs) {
if (params.height >= 0) {
@@ -704,9 +716,9 @@
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
} else if (params.width == LayoutParams.MATCH_PARENT) {
- childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.EXACTLY);
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY);
} else {
- childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.AT_MOST);
+ childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
}
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index db20549..acbb2b1 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -812,6 +812,26 @@
return mActionView != null && mActionView.isTitleTruncated();
}
+ @Override
+ public void setHomeAsUpIndicator(Drawable indicator) {
+ mActionView.setHomeAsUpIndicator(indicator);
+ }
+
+ @Override
+ public void setHomeAsUpIndicator(int resId) {
+ mActionView.setHomeAsUpIndicator(resId);
+ }
+
+ @Override
+ public void setHomeActionContentDescription(CharSequence description) {
+ mActionView.setHomeActionContentDescription(description);
+ }
+
+ @Override
+ public void setHomeActionContentDescription(int resId) {
+ mActionView.setHomeActionContentDescription(resId);
+ }
+
/**
* @hide
*/
diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java
new file mode 100644
index 0000000..e26b27d
--- /dev/null
+++ b/core/java/com/android/internal/os/BaseCommand.java
@@ -0,0 +1,146 @@
+/*
+**
+** Copyright 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.internal.os;
+
+import java.io.PrintStream;
+
+public abstract class BaseCommand {
+
+ protected String[] mArgs;
+ private int mNextArg;
+ private String mCurArgData;
+
+ // These are magic strings understood by the Eclipse plugin.
+ public static final String FATAL_ERROR_CODE = "Error type 1";
+ public static final String NO_SYSTEM_ERROR_CODE = "Error type 2";
+ public static final String NO_CLASS_ERROR_CODE = "Error type 3";
+
+ /**
+ * Call to run the command.
+ */
+ public void run(String[] args) {
+ if (args.length < 1) {
+ onShowUsage(System.out);
+ return;
+ }
+
+ mArgs = args;
+ mNextArg = 0;
+ mCurArgData = null;
+
+ try {
+ onRun();
+ } catch (IllegalArgumentException e) {
+ onShowUsage(System.err);
+ System.err.println();
+ System.err.println("Error: " + e.getMessage());
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Convenience to show usage information to error output.
+ */
+ public void showUsage() {
+ onShowUsage(System.err);
+ }
+
+ /**
+ * Convenience to show usage information to error output along
+ * with an error message.
+ */
+ public void showError(String message) {
+ onShowUsage(System.err);
+ System.err.println();
+ System.err.println(message);
+ }
+
+ /**
+ * Implement the command.
+ */
+ public abstract void onRun() throws Exception;
+
+ /**
+ * Print help text for the command.
+ */
+ public abstract void onShowUsage(PrintStream out);
+
+ /**
+ * Return the next option on the command line -- that is an argument that
+ * starts with '-'. If the next argument is not an option, null is returned.
+ */
+ public String nextOption() {
+ if (mCurArgData != null) {
+ String prev = mArgs[mNextArg - 1];
+ throw new IllegalArgumentException("No argument expected after \"" + prev + "\"");
+ }
+ if (mNextArg >= mArgs.length) {
+ return null;
+ }
+ String arg = mArgs[mNextArg];
+ if (!arg.startsWith("-")) {
+ return null;
+ }
+ mNextArg++;
+ if (arg.equals("--")) {
+ return null;
+ }
+ if (arg.length() > 1 && arg.charAt(1) != '-') {
+ if (arg.length() > 2) {
+ mCurArgData = arg.substring(2);
+ return arg.substring(0, 2);
+ } else {
+ mCurArgData = null;
+ return arg;
+ }
+ }
+ mCurArgData = null;
+ return arg;
+ }
+
+ /**
+ * Return the next argument on the command line, whatever it is; if there are
+ * no arguments left, return null.
+ */
+ public String nextArg() {
+ if (mCurArgData != null) {
+ String arg = mCurArgData;
+ mCurArgData = null;
+ return arg;
+ } else if (mNextArg < mArgs.length) {
+ return mArgs[mNextArg++];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return the next argument on the command line, whatever it is; if there are
+ * no arguments left, throws an IllegalArgumentException to report this to the user.
+ */
+ public String nextArgRequired() {
+ String arg = nextArg();
+ if (arg == null) {
+ String prev = mArgs[mNextArg - 1];
+ throw new IllegalArgumentException("Argument expected after \"" + prev + "\"");
+ }
+ return arg;
+ }
+}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 780f5b3..58b15e2 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -17,7 +17,7 @@
package com.android.internal.statusbar;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarNotification;
+import android.service.notification.StatusBarNotification;
/** @hide */
oneway interface IStatusBar
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 04e5bc9..c98ba8d 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -19,7 +19,7 @@
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
-import com.android.internal.statusbar.StatusBarNotification;
+import android.service.notification.StatusBarNotification;
/** @hide */
interface IStatusBarService
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index 9143c61..14afe21 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -84,7 +84,7 @@
dest.writeStrongInterface(method);
if (channel != null) {
dest.writeInt(1);
- channel.writeToParcel(dest, 0);
+ channel.writeToParcel(dest, flags);
} else {
dest.writeInt(0);
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index 2685046..7ca6c1b 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -107,7 +107,7 @@
}
public CharSequence getTitleCondensed() {
- return mTitleCondensed;
+ return mTitleCondensed != null ? mTitleCondensed : mTitle;
}
public boolean hasSubMenu() {
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index b99b39a..59ff597 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -93,6 +93,8 @@
private CharSequence mSubtitle;
private Drawable mIcon;
private Drawable mLogo;
+ private CharSequence mHomeDescription;
+ private int mHomeDescriptionRes;
private HomeView mHomeLayout;
private HomeView mExpandedHomeLayout;
@@ -288,6 +290,10 @@
initTitle();
}
+ if (mHomeDescriptionRes != 0) {
+ setHomeActionContentDescription(mHomeDescriptionRes);
+ }
+
if (mTabScrollView != null && mIncludeTabs) {
ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
if (lp != null) {
@@ -589,14 +595,43 @@
mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
} else {
mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ mUpGoerFive.setContentDescription(buildHomeContentDescription());
+ }
+ }
+
+ /**
+ * Compose a content description for the Home/Up affordance.
+ *
+ * <p>As this encompasses the icon/logo, title and subtitle all in one, we need
+ * a description for the whole wad of stuff that can be localized properly.</p>
+ */
+ private CharSequence buildHomeContentDescription() {
+ final CharSequence homeDesc;
+ if (mHomeDescription != null) {
+ homeDesc = mHomeDescription;
+ } else {
if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
- mUpGoerFive.setContentDescription(mContext.getResources().getText(
- R.string.action_bar_up_description));
+ homeDesc = mContext.getResources().getText(R.string.action_bar_up_description);
} else {
- mUpGoerFive.setContentDescription(mContext.getResources().getText(
- R.string.action_bar_home_description));
+ homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
}
}
+
+ final CharSequence title = getTitle();
+ final CharSequence subtitle = getSubtitle();
+ if (!TextUtils.isEmpty(title)) {
+ final String result;
+ if (!TextUtils.isEmpty(subtitle)) {
+ result = getResources().getString(
+ R.string.action_bar_home_subtitle_description_format,
+ title, subtitle, homeDesc);
+ } else {
+ result = getResources().getString(R.string.action_bar_home_description_format,
+ title, homeDesc);
+ }
+ return result;
+ }
+ return homeDesc;
}
public void setDisplayOptions(int options) {
@@ -1305,6 +1340,23 @@
}
}
+ public void setHomeAsUpIndicator(Drawable indicator) {
+ mHomeLayout.setUpIndicator(indicator);
+ }
+
+ public void setHomeAsUpIndicator(int resId) {
+ mHomeLayout.setUpIndicator(resId);
+ }
+
+ public void setHomeActionContentDescription(CharSequence description) {
+ mHomeDescription = description;
+ }
+
+ public void setHomeActionContentDescription(int resId) {
+ mHomeDescriptionRes = resId;
+ mHomeDescription = getResources().getText(resId);
+ }
+
static class SavedState extends BaseSavedState {
int expandedMenuItemId;
boolean isOverflowOpen;
@@ -1339,9 +1391,11 @@
}
private static class HomeView extends FrameLayout {
- private View mUpView;
+ private ImageView mUpView;
private ImageView mIconView;
private int mUpWidth;
+ private int mUpIndicatorRes;
+ private Drawable mDefaultUpIndicator;
private static final long DEFAULT_TRANSITION_DURATION = 150;
@@ -1366,6 +1420,25 @@
mIconView.setImageDrawable(icon);
}
+ public void setUpIndicator(Drawable d) {
+ mUpView.setImageDrawable(d != null ? d : mDefaultUpIndicator);
+ mUpIndicatorRes = 0;
+ }
+
+ public void setUpIndicator(int resId) {
+ mUpIndicatorRes = resId;
+ mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (mUpIndicatorRes != 0) {
+ // Reload for config change
+ setUpIndicator(mUpIndicatorRes);
+ }
+ }
+
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
onPopulateAccessibilityEvent(event);
@@ -1389,8 +1462,9 @@
@Override
protected void onFinishInflate() {
- mUpView = findViewById(com.android.internal.R.id.up);
+ mUpView = (ImageView) findViewById(com.android.internal.R.id.up);
mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
+ mDefaultUpIndicator = mUpView.getDrawable();
}
public int getStartOffset() {
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 9c44a59..9fa9fe4 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -246,6 +246,15 @@
return name;
}
+static void android_view_InputChannel_nativeDup(JNIEnv* env, jobject obj, jobject otherObj) {
+ NativeInputChannel* nativeInputChannel =
+ android_view_InputChannel_getNativeInputChannel(env, obj);
+ if (nativeInputChannel) {
+ android_view_InputChannel_setNativeInputChannel(env, otherObj,
+ new NativeInputChannel(nativeInputChannel->getInputChannel()->dup()));
+ }
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gInputChannelMethods[] = {
@@ -262,6 +271,8 @@
(void*)android_view_InputChannel_nativeWriteToParcel },
{ "nativeGetName", "()Ljava/lang/String;",
(void*)android_view_InputChannel_nativeGetName },
+ { "nativeDup", "(Landroid/view/InputChannel;)V",
+ (void*)android_view_InputChannel_nativeDup },
};
#define FIND_CLASS(var, className) \
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 576f831..e3a54a8 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -62,8 +62,8 @@
const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
for (size_t i = 0; i < ranges.size(); i++) {
const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
- env->CallVoidMethod(inputDeviceObj.get(), gInputDeviceClassInfo.addMotionRange,
- range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
+ env->CallVoidMethod(inputDeviceObj.get(), gInputDeviceClassInfo.addMotionRange, range.axis,
+ range.source, range.min, range.max, range.flat, range.fuzz, range.resolution);
if (env->ExceptionCheck()) {
return NULL;
}
@@ -90,7 +90,7 @@
"<init>", "(IILjava/lang/String;Ljava/lang/String;ZIILandroid/view/KeyCharacterMap;Z)V");
GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
- "addMotionRange", "(IIFFFF)V");
+ "addMotionRange", "(IIFFFFF)V");
return 0;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ffceb68..90e3b8d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2193,6 +2193,14 @@
android:description="@string/permdesc_accessNotifications"
android:protectionLevel="signature|system" />
+ <!-- Must be required by an {@link
+ android.service.notification.NotificationListenerService},
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
+ android:label="@string/permlab_bindNotificationListenerService"
+ android:description="@string/permdesc_bindNotificationListenerService"
+ android:protectionLevel="signature" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/layout/select_dialog.xml b/core/res/res/layout/select_dialog.xml
index 80d22f6..eb4d8d9 100644
--- a/core/res/res/layout/select_dialog.xml
+++ b/core/res/res/layout/select_dialog.xml
@@ -32,4 +32,5 @@
android:cacheColorHint="@null"
android:divider="?android:attr/listDividerAlertDialog"
android:scrollbars="vertical"
- android:overScrollMode="ifContentScrolls" />
+ android:overScrollMode="ifContentScrolls"
+ android:textAlignment="viewStart" />
diff --git a/core/res/res/layout/select_dialog_holo.xml b/core/res/res/layout/select_dialog_holo.xml
index 06a5d96..8a92283 100644
--- a/core/res/res/layout/select_dialog_holo.xml
+++ b/core/res/res/layout/select_dialog_holo.xml
@@ -30,4 +30,5 @@
android:cacheColorHint="@null"
android:divider="?android:attr/listDividerAlertDialog"
android:scrollbars="vertical"
- android:overScrollMode="ifContentScrolls" />
+ android:overScrollMode="ifContentScrolls"
+ android:textAlignment="viewStart" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4a15967..a0e1603 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1816,6 +1816,11 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_accessNotifications">Allows the app to retrieve, examine, and clear notifications, including those posted by other apps.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindNotificationListenerService">bind to a notification listener service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindNotificationListenerService">Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps.</string>
+
<!-- Policy administration -->
<!-- Title of policy access to limiting the user's password choices -->
@@ -2992,11 +2997,11 @@
<!-- [CHAR LIMIT=NONE] Stub notification title for an app running a service that has provided
a bad bad notification for itself. -->
<string name="app_running_notification_title"><xliff:g id="app_name">%1$s</xliff:g>
- running</string>
+ is running</string>
<!-- [CHAR LIMIT=NONE] Stub notification text for an app running a service that has provided
a bad bad notification for itself. -->
- <string name="app_running_notification_text"><xliff:g id="app_name">%1$s</xliff:g>
- is currently running</string>
+ <string name="app_running_notification_text">Touch for more information
+ or to stop the app.</string>
<!-- Preference framework strings. -->
<string name="ok">OK</string>
@@ -3508,6 +3513,9 @@
<string name="wallpaper_binding_label">Wallpaper</string>
<!-- Dialog title for user to select a different wallpaper from service list -->
<string name="chooser_wallpaper">Change wallpaper</string>
+ <!-- Label to show for a service that is running because it is observing
+ the user's notifications. -->
+ <string name="notification_listener_binding_label">Notification listener</string>
<!-- Do Not Translate: Alternate eri.xml -->
<string name="alternate_eri_file">/data/eri.xml</string>
@@ -3763,6 +3771,17 @@
<string name="action_bar_up_description">Navigate up</string>
<!-- Content description for the action menu overflow button. [CHAR LIMIT=NONE] -->
<string name="action_menu_overflow_description">More options</string>
+ <!-- Formatting string for describing the action bar's title/home/up affordance.
+ This is a single tappable "button" that includes the app icon, the Up indicator
+ (usually a "<" chevron) and the window title text.
+ %1$s is the title. %2$s is the description of what tapping/clicking the whole
+ thing is going to do. -->
+ <string name="action_bar_home_description_format">%1$s, %2$s</string>
+ <!-- Just like action_bar_home_description_format, but this one will be used
+ if the window is also providing subtitle text.
+ %1$s is the title. %2$s is the subtitle. %3$s is the description of what
+ tapping/clicking the whole thing is going to do. -->
+ <string name="action_bar_home_subtitle_description_format">%1$s, %2$s, %3$s</string>
<!-- Storage description for internal storage. [CHAR LIMIT=NONE] -->
<string name="storage_internal">Internal storage</string>
@@ -4069,4 +4088,5 @@
<string name="app_no_restricted_accounts">This application does not support accounts for limited users</string>
<!-- Message informing user that the requested activity could not be found [CHAR LIMIT=none] -->
<string name="app_not_found">No application found to handle this action</string>
+ <string name="revoke">Revoke</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ced0851..e06bcd1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -710,6 +710,7 @@
<java-symbol type="string" name="relationTypeSpouse" />
<java-symbol type="string" name="relative_time" />
<java-symbol type="string" name="reset" />
+ <java-symbol type="string" name="revoke" />
<java-symbol type="string" name="ringtone_default" />
<java-symbol type="string" name="ringtone_default_with_actual" />
<java-symbol type="string" name="ringtone_picker_title" />
@@ -870,6 +871,8 @@
<java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
<java-symbol type="string" name="config_appsAuthorizedForSharedAccounts" />
<java-symbol type="string" name="error_message_title" />
+ <java-symbol type="string" name="action_bar_home_description_format" />
+ <java-symbol type="string" name="action_bar_home_subtitle_description_format" />
<java-symbol type="plurals" name="abbrev_in_num_days" />
<java-symbol type="plurals" name="abbrev_in_num_hours" />
@@ -1638,6 +1641,7 @@
<java-symbol type="string" name="launch_warning_title" />
<java-symbol type="string" name="low_internal_storage_view_text" />
<java-symbol type="string" name="low_internal_storage_view_title" />
+ <java-symbol type="string" name="notification_listener_binding_label" />
<java-symbol type="string" name="report" />
<java-symbol type="string" name="select_input_method" />
<java-symbol type="string" name="select_keyboard_layout_notification_title" />
diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
index 40ecd14..072b842 100644
--- a/data/fonts/Roboto-Bold.ttf
+++ b/data/fonts/Roboto-Bold.ttf
Binary files differ
diff --git a/data/fonts/Roboto-BoldItalic.ttf b/data/fonts/Roboto-BoldItalic.ttf
index d9067c5..74919ff 100644
--- a/data/fonts/Roboto-BoldItalic.ttf
+++ b/data/fonts/Roboto-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
index 88e4a5b..bd57775 100644
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf
index 2ae4dec..13bf13a 100644
--- a/data/fonts/Roboto-Light.ttf
+++ b/data/fonts/Roboto-Light.ttf
Binary files differ
diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf
index 44177ef..130672a 100644
--- a/data/fonts/Roboto-LightItalic.ttf
+++ b/data/fonts/Roboto-LightItalic.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf
index f592adf..0ba95c9 100644
--- a/data/fonts/Roboto-Regular.ttf
+++ b/data/fonts/Roboto-Regular.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Thin.ttf b/data/fonts/Roboto-Thin.ttf
index 5ae4d7f..309c22d 100644
--- a/data/fonts/Roboto-Thin.ttf
+++ b/data/fonts/Roboto-Thin.ttf
Binary files differ
diff --git a/data/fonts/Roboto-ThinItalic.ttf b/data/fonts/Roboto-ThinItalic.ttf
index 9cd3927..0b53ba4 100644
--- a/data/fonts/Roboto-ThinItalic.ttf
+++ b/data/fonts/Roboto-ThinItalic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Bold.ttf b/data/fonts/RobotoCondensed-Bold.ttf
index 21c10f5..f0fd409 100644
--- a/data/fonts/RobotoCondensed-Bold.ttf
+++ b/data/fonts/RobotoCondensed-Bold.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-BoldItalic.ttf b/data/fonts/RobotoCondensed-BoldItalic.ttf
index d8edd2d..e67b02b 100644
--- a/data/fonts/RobotoCondensed-BoldItalic.ttf
+++ b/data/fonts/RobotoCondensed-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Italic.ttf b/data/fonts/RobotoCondensed-Italic.ttf
index 4dec2cf..a08414b 100644
--- a/data/fonts/RobotoCondensed-Italic.ttf
+++ b/data/fonts/RobotoCondensed-Italic.ttf
Binary files differ
diff --git a/data/fonts/RobotoCondensed-Regular.ttf b/data/fonts/RobotoCondensed-Regular.ttf
index 875ea1a..713fd30 100644
--- a/data/fonts/RobotoCondensed-Regular.ttf
+++ b/data/fonts/RobotoCondensed-Regular.ttf
Binary files differ
diff --git a/docs/html/about/versions/android-4.0.jd b/docs/html/about/versions/android-4.0.jd
index f2fd0c4..868227a 100644
--- a/docs/html/about/versions/android-4.0.jd
+++ b/docs/html/about/versions/android-4.0.jd
@@ -122,7 +122,7 @@
receiving the app uses it to invite the specified contact to that
social network. Most apps will be on the receiving-end of this operation. For example, the
built-in People app invokes the invite intent when the user selects "Add connection" for a specific
-social app that's listed in a person's contact details.</p>
+social app that's listed in a person's contact details.</p>
<p>To make your app visible as in the "Add connection" list, your app must provide a sync adapter to
sync contact information from your social network. You must then indicate to the system that your
@@ -327,7 +327,7 @@
function). You may provide multiple mipmap levels. If the output texture has not been bound to a
texture image, it will be automatically bound by the effect as a {@link
android.opengl.GLES20#GL_TEXTURE_2D} and with one mipmap level (0), which will have the same
-size as the input.</p>
+size as the input.</p>
<p>All effects listed in {@link android.media.effect.EffectFactory} are guaranteed to be supported.
However, some additional effects available from external libraries are not supported by all devices,
@@ -452,7 +452,7 @@
value is greater than zero. Also, some devices may not support identification of eyes and mouth,
in which case, those fields in the {@link android.hardware.Camera.Face} object will be null.</p>
-
+
<h4>Focus and metering areas</h4>
<p>Camera apps can now control the areas that the camera uses for focus and for metering white
@@ -495,7 +495,7 @@
<h4>Other camera features</h4>
-<ul>
+<ul>
<li>While recording video, you can now call {@link android.hardware.Camera#takePicture
takePicture()} to save a photo without interrupting the video session. Before doing so, you should
call {@link android.hardware.Camera.Parameters#isVideoSnapshotSupported} to be sure the hardware
@@ -775,7 +775,7 @@
<li>When invoked, the {@link
android.view.View#sendAccessibilityEvent sendAccessibilityEvent()} and {@link
android.view.View#sendAccessibilityEventUnchecked sendAccessibilityEventUnchecked()} methods defer
-to {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}.
+to {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}.
<p>Custom implementations of {@link android.view.View} might want to implement {@link
android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} to
attach additional accessibility information to the {@link
@@ -1022,46 +1022,6 @@
-<h3 id="RenderScript">RenderScript</h3>
-
-<p>Three major features have been added to RenderScript:</p>
-
-<ul>
- <li>Off-screen rendering to a framebuffer object</li>
- <li>Rendering inside a view</li>
- <li>RS for each from the framework APIs</li>
-</ul>
-
-<p>The {@link android.renderscript.Allocation} class now supports a {@link
-android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} memory space, which allows you to
-render things directly into the {@link android.renderscript.Allocation} and use it as a framebuffer
-object.</p>
-
-<p>{@link android.renderscript.RSTextureView} provides a means to display RenderScript graphics
-inside of a {@link android.view.View}, unlike {@link android.renderscript.RSSurfaceView}, which
-creates a separate window. This key difference allows you to do things such as move, transform, or
-animate an {@link android.renderscript.RSTextureView} as well as draw RenderScript graphics inside
-a view that lies within an activity layout.</p>
-
-<p>The {@link android.renderscript.Script#forEach Script.forEach()} method allows you to call
-RenderScript compute scripts from the VM level and have them automatically delegated to available
-cores on the device. You do not use this method directly, but any compute RenderScript that you
-write will have a {@link android.renderscript.Script#forEach forEach()} method that you can call in
-the reflected RenderScript class. You can call the reflected {@link
-android.renderscript.Script#forEach forEach()} method by passing in an input {@link
-android.renderscript.Allocation} to process, an output {@link android.renderscript.Allocation} to
-write the result to, and a {@link android.renderscript.FieldPacker} data structure in case the
-RenderScript needs more information. Only one of the {@link android.renderscript.Allocation}s is
-necessary and the data structure is optional.</p>
-
-
-
-
-
-
-
-
-
<h3 id="Enterprise">Enterprise</h3>
<p>Android 4.0 expands the capabilities for enterprise application with the following features.</p>
@@ -1758,7 +1718,7 @@
notes for more information.</li>
</ul>
</dd>
-
+
<dt><a href="android-3.1.html">Android 3.1</a></dt>
<dd>
<ul>
@@ -1781,7 +1741,7 @@
notes for many more new APIs.</li>
</ul>
</dd>
-
+
<dt><a href="android-3.2.html">Android 3.2</a></dt>
<dd>
<ul>
diff --git a/docs/html/guide/topics/graphics/renderscript/graphics.jd b/docs/html/guide/topics/graphics/renderscript/graphics.jd
deleted file mode 100644
index 58676ea..0000000
--- a/docs/html/guide/topics/graphics/renderscript/graphics.jd
+++ /dev/null
@@ -1,994 +0,0 @@
-page.title=Graphics
-parent.title=Renderscript
-parent.link=index.html
-
-@jd:body
-
- <div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
-
- <ol>
- <li>
- <a href="#creating-graphics-rs">Creating a Graphics Renderscript</a>
- <ol>
- <li><a href="#creating-native">Creating the Renderscript file</a></li>
- <li><a href="#creating-entry">Creating the Renderscript entry point class</a></li>
- <li><a href="#creating-view">Creating the view class</a></li>
- <li><a href="#creating-activity">Creating the activity class</a></li>
- </ol>
- </li>
- <li>
- <a href="#drawing">Drawing</a>
- <ol>
- <li><a href="#drawing-rsg">Simple drawing</a></li>
- <li><a href="#drawing-mesh">Drawing with a mesh</a></li>
- </ol>
- </li>
- <li>
- <a href="#shaders">Shaders</a>
- <ol>
- <li><a href="#shader-bindings">Shader bindings</a></li>
- <li><a href="#shader-sampler">Defining a sampler</a></li>
- </ol>
- </li>
- <li>
- <a href="#fbo">Rendering to a Framebuffer Object</a>
- </li>
- </ol>
-
- <h2>Related Samples</h2>
-
- <ol>
- <li><a href="{@docRoot}resources/samples/RenderScript/Balls/index.html">Balls</a></li>
-
- <li><a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a></li>
-
- <li><a href="{@docRoot}resources/samples/RenderScript/FountainFbo/index.html">FountainFbo</a></li>
-
- <li><a href="{@docRoot}resources/samples/RenderScript/HelloWorld/index.html">Hello
-World</a></li>
-
- <li><a
-href="{@docRoot}resources/samples/RenderScript/MiscSamples/index.html">Misc Samples</a></li>
- </ol>
- </div>
- </div>
-
- <p>Renderscript provides a number of graphics APIs for rendering, both at the Android
- framework level as well as at the Renderscript runtime level. For instance, the Android framework APIs let you
- create meshes and define shaders to customize the graphical rendering pipeline. The native
- Renderscript graphics APIs let you draw the actual meshes to render your scene. You need to
- be familiar with both APIs to appropriately render graphics on an Android-powered device.</p>
-
- <h2 id="creating-graphics-rs">Creating a Graphics Renderscript</h2>
-
- <p>Renderscript applications require various layers of code, so it is useful to create the following
- files to help keep your application organized:</p>
-
- <dl>
- <dt>The Renderscript <code>.rs</code> file</dt>
-
- <dd>This file contains the logic to do the graphics rendering.</dd>
-
- <dt>The Renderscript entry point <code>.java</code> class</dt>
-
- <dd>This class allows the view class to interact with the code defined in the <code>.rs</code>
- file. This class contains a Renderscript object (instance of
- <code>ScriptC_<em>renderscript_file</em></code>), which allows your Android framework code to
- call the Renderscript code. In general, this class does much of the setup for Renderscript
- such as shader and mesh building and memory allocation and binding. The SDK samples follow the
- convention of naming this file ActivityRS.java,
- where Activity is the name of your main activity class.</dd>
-
- <dt>The view <code>.java</code> class</dt>
-
- <dd>This class extends {@link android.renderscript.RSSurfaceView} or {@link
- android.renderscript.RSTextureView} to provide a surface to render on. A {@link
- android.renderscript.RSSurfaceView} consumes a whole window, but a {@link
- android.renderscript.RSTextureView} allows you to draw Renderscript graphics inside of a
- view and add it to a {@link android.view.ViewGroup} alongside
- other views. In this class, you create a {@link android.renderscript.RenderScriptGL} context object
- with a call to {@link android.renderscript.RSSurfaceView#createRenderScriptGL
- RSSurfaceView.createRenderscriptGL()} or {@link android.renderscript.RSTextureView#createRenderScriptGL
- RSTextureView.createRenderscriptGL()}. The {@link android.renderscript.RenderScriptGL} context object
- contains information about the current rendering state of Renderscript such as the vertex and
- fragment shaders. You pass this context object to the Renderscript entry point class, so that
- class can modify the rendering context if needed and bind the Renderscript code to the context. Once bound,
- the view class can use the Renderscript code to display graphics.
- The view class should also implement callbacks for events inherited from {@link
- android.view.View}, such as {@link android.view.View#onTouchEvent onTouchEvent()} and {@link
- android.view.View#onKeyDown onKeyDown()} if you want to detect these types of user interactions.
- The SDK samples follow the convention of naming this file ActivityView.java,
- where Activity is the name of your main activity class</dd>
-
- <dt>The activity <code>.java</code> class</dt>
-
- <dd>This class is the main activity class and sets your {@link android.renderscript.RSSurfaceView} as the main content
- view for this activity or uses the {@link android.renderscript.RSTextureView} alongside other views.</dd>
- </dl>
- <p>Figure 1 describes how these classes interact with one another in a graphics Renderscript:</p>
-
- <img src="{@docRoot}images/rs_graphics.png">
- <p class="img-caption"><strong>Figure 1.</strong> Graphics Renderscript overview</p>
-
-
- <p>The following sections describe how to create an application that uses a graphics Renderscript by using
- the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Renderscript Fountain
- sample</a> that is provided in the SDK as a guide (some code has been modified from its original
- form for simplicity).</p>
-
- <h3 id="creating-native">Creating the Renderscript file</h3>
-
- <p>Your Renderscript code resides in <code>.rs</code> and <code>.rsh</code> (headers) files in the
- <code><project_root>/src/</code> directory. This code contains the logic to render your
- graphics and declares all other necessary items such as variables, structs,
- and pointers. Every graphics <code>.rs</code> file generally contains the following items:</p>
-
- <ul>
- <li>A pragma declaration (<code>#pragma rs java_package_name(<em>package.name</em>)</code>) that declares
- the package name of the <code>.java</code> reflection of this Renderscript.</li>
-
- <li>A pragma declaration (<code>#pragma version(1)</code>) that declares the version of Renderscript that
- you are using (1 is the only value for now).</li>
-
- <li>A <code>#include "rs_graphics.rsh"</code> declaration.</li>
-
- <li>A <code>root()</code> function. This is the main worker function for your Renderscript and
- calls Renderscript graphics functions to render scenes. This function is called every time a
- frame refresh occurs, which is specified as its return value. A <code>0</code> (zero) specified for
- the return value says to only render the frame when a property of the scene that you are
- rendering changes. A non-zero positive integer specifies the refresh rate of the frame in
- milliseconds.
-
- <p class="note"><strong>Note:</strong> The Renderscript runtime makes its best effort to
- refresh the frame at the specified rate. For example, if you are creating a live wallpaper
- and set the return value to 20, the Renderscript runtime renders the wallpaper at 50fps if it has just
- enough or more resources to do so. It renders as fast as it can if not enough resources
- are available.</p>
-
- <p>For more information on using the Renderscript graphics functions, see the <a href=
- "#drawing">Drawing</a> section.</p>
- </li>
-
- <li>An <code>init()</code> function. This allows you to do initialization of your
- Renderscript before the <code>root()</code> function runs, such as assigning values to variables. This
- function runs once and is called automatically when the Renderscript starts, before anything
- else in your Renderscript. Creating this function is optional.</li>
-
- <li>Any variables, pointers, and structures that you wish to use in your Renderscript code (can
- be declared in <code>.rsh</code> files if desired)</li>
- </ul>
-
- <p>The following code shows how the <code>fountain.rs</code> file is implemented:</p>
- <pre>
-#pragma version(1)
-
-// Tell which java package name the reflected files should belong to
-#pragma rs java_package_name(com.example.android.rs.fountain)
-
-//declare shader binding
-#pragma stateFragment(parent)
-
-// header with graphics APIs, must include explicitly
-#include "rs_graphics.rsh"
-
-static int newPart = 0;
-
-// the mesh to render
-rs_mesh partMesh;
-
-// the point representing where a particle is rendered
-typedef struct __attribute__((packed, aligned(4))) Point {
- float2 delta;
- float2 position;
- uchar4 color;
-} Point_t;
-Point_t *point;
-
-// main worker function that renders particles onto the screen
-int root() {
- float dt = min(rsGetDt(), 0.1f);
- rsgClearColor(0.f, 0.f, 0.f, 1.f);
- const float height = rsgGetHeight();
- const int size = rsAllocationGetDimX(rsGetAllocation(point));
- float dy2 = dt * (10.f);
- Point_t * p = point;
- for (int ct=0; ct < size; ct++) {
- p->delta.y += dy2;
- p->position += p->delta;
- if ((p->position.y > height) && (p->delta.y > 0)) {
- p->delta.y *= -0.3f;
- }
- p++;
- }
-
- rsgDrawMesh(partMesh);
- return 1;
-}
-
-// adds particles to the screen to render
-static float4 partColor[10];
-void addParticles(int rate, float x, float y, int index, bool newColor)
-{
- if (newColor) {
- partColor[index].x = rsRand(0.5f, 1.0f);
- partColor[index].y = rsRand(1.0f);
- partColor[index].z = rsRand(1.0f);
- }
- float rMax = ((float)rate) * 0.02f;
- int size = rsAllocationGetDimX(rsGetAllocation(point));
- uchar4 c = rsPackColorTo8888(partColor[index]);
-
- Point_t * np = &point[newPart];
- float2 p = {x, y};
- while (rate--) {
- float angle = rsRand(3.14f * 2.f);
- float len = rsRand(rMax);
- np->delta.x = len * sin(angle);
- np->delta.y = len * cos(angle);
- np->position = p;
- np->color = c;
- newPart++;
- np++;
- if (newPart >= size) {
- newPart = 0;
- np = &point[newPart];
- }
- }
-}
-</pre>
-
- <h3 id="creating-entry">Creating the Renderscript entry point class</h3>
-
- <p>When you create a Renderscript (<code>.rs</code>) file, it is helpful to create a
- corresponding Android framework class that is an entry point into the <code>.rs</code> file.
- The most important thing this class does is receive a {@link android.renderscript.RenderScriptGL} rendering context
- object from the <a href="#creating-view">view class</a> and binds the actual Renderscript
- code to the rendering context. This notifies your view class of the code that it needs
- to render graphics.
- </p>
-
- <p>In addition, this class should contain all of the things needed to set up Renderscript.
- Some important things that you need to do in this class are:</p>
-
- <ul>
- <li>Create a Renderscript object
- <code>ScriptC_<em>rs_filename</em></code>. The Renderscript object is attached to the Renderscript bytecode, which is platform-independent and
- gets compiled on the device when the Renderscript application runs. The bytecode is referenced
- as a raw resource and is passed into the constructor for the Renderscript object.
- For example, this is how the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a>
- sample creates the Renderscript object:
- <pre>
- RenderScriptGL rs; //obtained from the view class
- Resources res; //obtained from the view class
- ...
- ScriptC_fountain mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
- </pre>
- </li>
- <li>Allocate any necessary memory and bind it to your Renderscript code via the Renderscript object.</li>
- <li>Build any necessary meshes and bind them to the Renderscript code via the Renderscript object.</li>
- <li>Create any necessary programs and bind them to the Renderscript code via the Renderscript object.</li>
- </ul>
-
- <p>The following code shows how the <a href=
- "{@docRoot}resources/samples/RenderScript/Fountain/src/com/example/android/rs/fountain/FountainRS.html">
- FountainRS</a> class is implemented:</p>
- <pre>
-package com.example.android.rs.fountain;
-
-import android.content.res.Resources;
-import android.renderscript.*;
-import android.util.Log;
-
-public class FountainRS {
- public static final int PART_COUNT = 50000;
-
- public FountainRS() {
- }
-
- /**
- * This provides us with the Renderscript context and resources
- * that allow us to create the Renderscript object
- */
- private Resources mRes;
- private RenderScriptGL mRS;
-
- // Renderscript object
- private ScriptC_fountain mScript;
-
- // Called by the view class to initialize the Renderscript context and renderer
- public void init(RenderScriptGL rs, Resources res) {
- mRS = rs;
- mRes = res;
-
- /**
- * Create a shader and bind to the Renderscript context
- */
- ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
- pfb.setVaryingColor(true);
- rs.bindProgramFragment(pfb.create());
-
- /**
- * Allocate memory for the particles to render and create the mesh to draw
- */
- ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
- Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
- smb.addVertexAllocation(points.getAllocation());
- smb.addIndexSetType(Mesh.Primitive.POINT);
- Mesh sm = smb.create();
-
- /**
- * Create and bind the Renderscript object to the Renderscript context
- */
- mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
- mScript.set_partMesh(sm);
- mScript.bind_point(points);
- mRS.bindRootScript(mScript);
- }
-
- boolean holdingColor[] = new boolean[10];
-
- /**
- * Calls Renderscript functions (invoke_addParticles)
- * via the Renderscript object to add particles to render
- * based on where a user touches the screen.
- */
- public void newTouchPosition(float x, float y, float pressure, int id) {
- if (id >= holdingColor.length) {
- return;
- }
- int rate = (int)(pressure * pressure * 500.f);
- if (rate > 500) {
- rate = 500;
- }
- if (rate > 0) {
- mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]);
- holdingColor[id] = true;
- } else {
- holdingColor[id] = false;
- }
-
- }
-}
-</pre>
-
-
- <h3 id="creating-view">Creating the view class</h3>
-
-
- <p>To display graphics, you need a view to render on. Create a class that extends {@link
- android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. This class
- allows you to create a {@link android.renderscript.RenderScriptGL} context object by calling and
- pass it to the Rendscript entry point class to bind the two. Once bound, the content is aware
- of the code that it needs to use to render graphics with. If your Renderscript code
- depends on any type of information that the view is aware of, such as touches from the user,
- you can also use this class to relay that information to the Renderscript entry point class.
- The following code shows how the <code>FountainView</code> class is implemented:</p>
- <pre>
-package com.example.android.rs.fountain;
-
-import android.renderscript.RSTextureView;
-import android.renderscript.RenderScriptGL;
-import android.content.Context;
-import android.view.MotionEvent;
-
-public class FountainView extends RSTextureView {
-
- public FountainView(Context context) {
- super(context);
- }
- // Renderscript context
- private RenderScriptGL mRS;
- // Renderscript entry point object that calls Renderscript code
- private FountainRS mRender;
-
- /**
- * Create Renderscript context and initialize Renderscript entry point
- */
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- android.util.Log.e("rs", "onAttachedToWindow");
- if (mRS == null) {
- RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
- mRS = createRenderScriptGL(sc);
- mRender = new FountainRS();
- mRender.init(mRS, getResources());
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- android.util.Log.e("rs", "onDetachedFromWindow");
- if (mRS != null) {
- mRS = null;
- destroyRenderScriptGL();
- }
- }
-
-
- /**
- * Use callbacks to relay data to Renderscript entry point class
- */
- @Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- int act = ev.getActionMasked();
- if (act == ev.ACTION_UP) {
- mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0));
- return false;
- } else if (act == MotionEvent.ACTION_POINTER_UP) {
- // only one pointer going up, we can get the index like this
- int pointerIndex = ev.getActionIndex();
- int pointerId = ev.getPointerId(pointerIndex);
- mRender.newTouchPosition(0, 0, 0, pointerId);
- }
- int count = ev.getHistorySize();
- int pcount = ev.getPointerCount();
-
- for (int p=0; p < pcount; p++) {
- int id = ev.getPointerId(p);
- mRender.newTouchPosition(ev.getX(p),
- ev.getY(p),
- ev.getPressure(p),
- id);
-
- for (int i=0; i < count; i++) {
- mRender.newTouchPosition(ev.getHistoricalX(p, i),
- ev.getHistoricalY(p, i),
- ev.getHistoricalPressure(p, i),
- id);
- }
- }
- return true;
- }
-}
-</pre>
-
- <h3 id="creating-activity">Creating the activity class</h3>
-
- <p>Applications that use Renderscript still behave like normal Android applications, so you
- need an activity class that handles activity lifecycle callback events appropriately. The activity class
- also sets your {@link android.renderscript.RSSurfaceView} view class to be the main content view of the
- activity or uses your {@link android.renderscript.RSTextureView}
- in a {@link android.view.ViewGroup} alongside other views.</p>
-
- <p>The following code shows how the <a href="{@docRoot}resources/samples/RenderScript/Fountain/index.html">Fountain</a>
- sample declares its activity class:</p>
- <pre>
-package com.example.android.rs.fountain;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-
-public class Fountain extends Activity {
-
- private static final String LOG_TAG = "libRS_jni";
- private static final boolean DEBUG = false;
- private static final boolean LOG_ENABLED = false;
-
- private FountainView mView;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- // Create our Preview view and set it as
- // the content of our activity
- mView = new FountainView(this);
- setContentView(mView);
- }
-
- @Override
- protected void onResume() {
- Log.e("rs", "onResume");
-
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onResume();
- mView.resume();
- }
-
- @Override
- protected void onPause() {
- Log.e("rs", "onPause");
-
- // Ideally a game should implement onResume() and onPause()
- // to take appropriate action when the activity looses focus
- super.onPause();
- mView.pause();
-
- }
-
- static void log(String message) {
- if (LOG_ENABLED) {
- Log.v(LOG_TAG, message);
- }
- }
-}
-</pre>
-
-<p>Now that you have an idea of what is involved in a Renderscript graphics application, you can
-start building your own. It might be easiest to begin with one of the
-<a href="{@docRoot}resources/samples/RenderScript/index.html">Renderscript samples</a> as a starting
-point if this is your first time using Renderscript.</p>
-
- <h2 id="drawing">Drawing</h2>
- <p>The following sections describe how to use the graphics functions to draw with Renderscript.</p>
-
- <h3 id="drawing-rsg">Simple drawing</h3>
-
- <p>The native Renderscript APIs provide a few convenient functions to easily draw a polygon or text to
- the screen. You call these in your <code>root()</code> function to have them render to the {@link
- android.renderscript.RSSurfaceView} or {@link android.renderscript.RSTextureView}. These functions are
- available for simple drawing and should not be used for complex graphics rendering:</p>
-
- <ul>
- <li><code>rsgDrawRect()</code>: Sets up a mesh and draws a rectangle to the screen. It uses the
- top left vertex and bottom right vertex of the rectangle to draw.</li>
-
- <li><code>rsgDrawQuad()</code>: Sets up a mesh and draws a quadrilateral to the screen.</li>
-
- <li><code>rsgDrawQuadTexCoords()</code>: Sets up a mesh and draws a quadrilateral to the screen
- using the provided coordinates of a texture.</li>
-
- <li><code>rsgDrawText()</code>: Draws specified text to the screen. Use <code>rsgFontColor()</code>
- to set the color of the text.</li>
- </ul>
-
- <h3 id="drawing-mesh">Drawing with a mesh</h3>
-
- <p>When you want to render complex scenes to the screen, instantiate a {@link
- android.renderscript.Mesh} and draw it with <code>rsgDrawMesh()</code>. A {@link
- android.renderscript.Mesh} is a collection of allocations that represent vertex data (positions,
- normals, texture coordinates) and index data that provides information on how to draw triangles
- and lines with the provided vertex data. You can build a Mesh in three different ways:</p>
-
- <ul>
- <li>Build the mesh with the {@link android.renderscript.Mesh.TriangleMeshBuilder} class, which
- allows you to specify a set of vertices and indices for each triangle that you want to draw.</li>
-
- <li>Build the mesh using an {@link android.renderscript.Allocation} or a set of {@link
- android.renderscript.Allocation}s with the {@link android.renderscript.Mesh.AllocationBuilder}
- class. This approach allows you to build a mesh with vertices already stored in memory, which allows you
- to specify the vertices in Renderscript or Android framework code.</li>
-
- <li>Build the mesh with the {@link android.renderscript.Mesh.Builder} class. You should use
- this convenience method when you know the data types you want to use to build your mesh, but
- don't want to make separate memory allocations like with {@link
- android.renderscript.Mesh.AllocationBuilder}. You can specify the types that you want and this
- mesh builder automatically creates the memory allocations for you.</li>
- </ul>
-
- <p>To create a mesh using the {@link android.renderscript.Mesh.TriangleMeshBuilder}, you need to
- supply it with a set of vertices and the indices for the vertices that comprise the triangle. For
- example, the following code specifies three vertices, which are added to an internal array,
- indexed in the order they were added. The call to {@link
- android.renderscript.Mesh.TriangleMeshBuilder#addTriangle addTriangle()} draws the triangle with
- vertex 0, 1, and 2 (the vertices are drawn counter-clockwise).</p>
- <pre>
-int float2VtxSize = 2;
-Mesh.TriangleMeshBuilder triangles = new Mesh.TriangleMeshBuilder(renderscriptGL,
-float2VtxSize, Mesh.TriangleMeshBuilder.COLOR);
-triangles.addVertex(300.f, 300.f);
-triangles.addVertex(150.f, 450.f);
-triangles.addVertex(450.f, 450.f);
-triangles.addTriangle(0 , 1, 2);
-Mesh smP = triangle.create(true);
-script.set_mesh(smP);
-</pre>
-
- <p>To draw a mesh using the {@link android.renderscript.Mesh.AllocationBuilder}, you need to
- supply it with one or more allocations that contain the vertex data:</p>
- <pre>
-Allocation vertices;
-
-...
-Mesh.AllocationBuilder triangle = new Mesh.AllocationBuilder(mRS);
-smb.addVertexAllocation(vertices.getAllocation());
-smb.addIndexSetType(Mesh.Primitive.TRIANGLE);
-Mesh smP = smb.create();
-script.set_mesh(smP);
-</pre>
-
- <p>In your Renderscript code, draw the built mesh to the screen:</p>
- <pre>
-rs_mesh mesh;
-...
-
-int root(){
-...
-rsgDrawMesh(mesh);
-...
-return 0; //specify a non zero, positive integer to specify the frame refresh.
- //0 refreshes the frame only when the mesh changes.
-}
-</pre>
-
- <h2 id="shader">Programs</h2>
-
- <p>You can attach four program objects to the {@link android.renderscript.RenderScriptGL} context
- to customize the rendering pipeline. For example, you can create vertex and fragment shaders in
- GLSL or build a raster program object that controls culling. The four programs mirror a
- traditional graphical rendering pipeline:</p>
-
- <table>
- <tr>
- <th>Android Object Type</th>
-
- <th>Renderscript Native Type</th>
-
- <th>Description</th>
- </tr>
-
- <tr>
- <td>{@link android.renderscript.ProgramVertex}</td>
-
- <td>rs_program_vertex</td>
-
- <td>
- <p>The Renderscript vertex program, also known as a vertex shader, describes the stage in
- the graphics pipeline responsible for manipulating geometric data in a user-defined way.
- The object is constructed by providing Renderscript with the following data:</p>
-
- <ul>
- <li>An {@link android.renderscript.Element} describing its varying inputs or attributes</li>
-
- <li>GLSL shader string that defines the body of the program</li>
-
- <li>a {@link android.renderscript.Type} that describes the layout of an
- Allocation containing constant or uniform inputs</li>
- </ul>
-
- <p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
- graphics context by calling {@link android.renderscript.RenderScriptGL#bindProgramVertex
- bindProgramVertex()}. It is then used for all subsequent draw calls until you bind a new
- program. If the program has constant inputs, the user needs to bind an allocation
- containing those inputs. The allocation's type must match the one provided during creation.
- </p>
-
- <p>The Renderscript runtime then does all the necessary plumbing to send those constants to
- the graphics hardware. Varying inputs to the shader, such as position, normal, and texture
- coordinates are matched by name between the input {@link android.renderscript.Element}
- and the mesh object that is being drawn. The signatures don't have to be exact or in any
- strict order. As long as the input name in the shader matches a channel name and size
- available on the mesh, the Renderscript runtime handles connecting the two. Unlike OpenGL
- there is no need to link the vertex and fragment programs.</p>
-
- <p>To bind shader constants to the program, declare a <code>struct</code> that contains the necessary
- shader constants in your Renderscript code. This <code>struct</code> is generated into a
- reflected class that you can use as a constant input element during the program's creation.
- It is an easy way to create an instance of this <code>struct</code> as an allocation. You would then
- bind this {@link android.renderscript.Allocation} to the program and the
- Renderscript runtime sends the data that is contained in the <code>struct</code> to the hardware
- when necessary. To update shader constants, you change the values in the
- {@link android.renderscript.Allocation} and notify the Renderscript
- code of the change.</p>
-
- <p>The {@link android.renderscript.ProgramVertexFixedFunction.Builder} class also
- lets you build a simple vertex shader without writing GLSL code.
- </p>
- </td>
- </tr>
-
- <tr>
- <td>{@link android.renderscript.ProgramFragment}</td>
-
- <td>rs_program_fragment</td>
-
- <td>
- <p>The Renderscript fragment program, also known as a fragment shader, is responsible for
- manipulating pixel data in a user-defined way. It's constructed from a GLSL shader string
- containing the program body, texture inputs, and a {@link android.renderscript.Type}
- object that describes the constants
- used by the program. Like the vertex programs, when an {@link android.renderscript.Allocation}
- with constant input
- values is bound to the shader, its values are sent to the graphics program automatically.
- Note that the values inside the {@link android.renderscript.Allocation} are not explicitly tracked.
- If they change between two draw calls using the same program object, notify the runtime of that change by
- calling <code>rsgAllocationSyncAll()</code>, so it can send the new values to hardware. Communication
- between the vertex and fragment programs is handled internally in the GLSL code. For
- example, if the fragment program is expecting a varying input called <code>varTex0</code>, the GLSL code
- inside the program vertex must provide it.</p>
-
- <p>To bind shader constructs to the program, declare a <code>struct</code> that contains the necessary
- shader constants in your Renderscript code. This <code>struct</code> is generated into a
- reflected class that you can use as a constant input element during the program's creation.
- It is an easy way to create an instance of this <code>struct</code> as an allocation. You would then
- bind this {@link android.renderscript.Allocation} to the program and the
- Renderscript runtime sends the data that is contained in the <code>struct</code> to the hardware
- when necessary. To update shader constants, you change the values in the
- {@link android.renderscript.Allocation} and notify the Renderscript
- code of the change.</p>
-
- <p>The {@link android.renderscript.ProgramFragmentFixedFunction.Builder} class also
- lets you build a simple fragment shader without writing GLSL code.
- </p>
- </td>
- </tr>
-
- <tr>
- <td>{@link android.renderscript.ProgramStore}</td>
-
- <td>rs_program_store</td>
-
- <td>The Renderscript store program contains a set of parameters that control how the graphics
- hardware writes to the framebuffer. It could be used to enable and disable depth writes and
- testing, setup various blending modes for effects like transparency and define write masks
- for color components.</td>
- </tr>
-
- <tr>
- <td>{@link android.renderscript.ProgramRaster}</td>
-
- <td>rs_program_raster</td>
-
- <td>The Renderscript raster program is primarily used to specify whether point sprites are enabled and to
- control the culling mode. By default back faces are culled.</td>
- </tr>
- </table>
-
- <p>The following example defines a vertex shader in GLSL and binds it to a Renderscript context object:</p>
- <pre>
- private RenderScriptGL glRenderer; //rendering context
- private ScriptField_Point mPoints; //vertices
- private ScriptField_VpConsts mVpConsts; //shader constants
-
- ...
-
- ProgramVertex.Builder sb = new ProgramVertex.Builder(glRenderer);
- String t = "varying vec4 varColor;\n" +
- "void main() {\n" +
- " vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
- " pos.xy = ATTRIB_position;\n" +
- " gl_Position = UNI_MVP * pos;\n" +
- " varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
- " gl_PointSize = ATTRIB_size;\n" +
- "}\n";
- sb.setShader(t);
- sb.addConstant(mVpConsts.getType());
- sb.addInput(mPoints.getElement());
- ProgramVertex pvs = sb.create();
- pvs.bindConstants(mVpConsts.getAllocation(), 0);
- glRenderer.bindProgramVertex(pvs);
-</pre>
-
-
- <p>The <a href=
- "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
- RsRenderStatesRS</a> sample has many examples on how to create a shader without writing GLSL.</p>
-
- <h3 id="shader-bindings">Program bindings</h3>
-
- <p>You can also declare four pragmas that control default program bindings to the {@link
- android.renderscript.RenderScriptGL} context when the script is executing:</p>
-
- <ul>
- <li><code>stateVertex</code></li>
-
- <li><code>stateFragment</code></li>
-
- <li><code>stateRaster</code></li>
-
- <li><code>stateStore</code></li>
- </ul>
-
- <p>The possible values for each pragma are <code>parent</code> or <code>default</code>. Using
- <code>default</code> binds the shaders to the graphical context with the system defaults.</p>
-
- <p>Using <code>parent</code> binds the shaders in the same manner as it is bound in the calling
- script. If this is the root script, the parent state is taken from the bind points that are set
- by the {@link android.renderscript.RenderScriptGL} bind methods.</p>
-
- <p>For example, you can define this at the top of your graphics Renderscript code to have
- the vertex and store programs inherent the bind properties from their parent scripts:</p>
- <pre>
-#pragma stateVertex(parent)
-#pragma stateStore(parent)
-</pre>
-
- <h3 id="shader-sampler">Defining a sampler</h3>
-
- <p>A {@link android.renderscript.Sampler} object defines how data is extracted from textures.
- Samplers are bound to a {@link android.renderscript.ProgramFragment} alongside the texture
- whose sampling they control. These
- objects are used to specify such things as edge clamping behavior, whether mip-maps are used, and
- the amount of anisotropy required. There might be situations where hardware does not support the
- desired behavior of the sampler. In these cases, the Renderscript runtime attempts to provide the
- closest possible approximation. For example, the user requested 16x anisotropy, but only 8x was
- set because it's the best available on the hardware.</p>
-
- <p>The <a href=
- "{@docRoot}resources/samples/RenderScript/MiscSamples/src/com/example/android/rs/miscsamples/RsRenderStatesRS.html">
- RsRenderStatesRS</a> sample has many examples on how to create a sampler and bind it to a
- Fragment program.</p>
-
-
-
-<h2 id="fbo">Rendering to a Framebuffer Object</h2>
-
-<p>Framebuffer objects allow you to render offscreen instead of in the default onscreen
-framebuffer. This approach might be useful for situations where you need to post-process a texture before
-rendering it to the screen, or when you want to composite two scenes in one such as rendering a rear-view
-mirror of a car. There are two buffers associated with a framebuffer object: a color buffer
-and a depth buffer. The color buffer (required) contains the actual pixel data of the scene
-that you are rendering, and the depth buffer (optional) contains the values necessary to figure
-out what vertices are drawn depending on their z-values.</p>
-
-<p>In general, you need to do the following to render to a framebuffer object:</p>
-
-<ul>
- <li>Create {@link android.renderscript.Allocation} objects for the color buffer and
- depth buffer (if needed). Specify the {@link
- android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} usage attribute for these
- allocations to notify the Renderscript runtime to use these allocations for the framebuffer
- object. For the color buffer allocation, you most likely need to declare the {@link
- android.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} usage attribute
- to use the color buffer as a texture, which is the most common use of the framebuffer object.</li>
-
- <li>Tell the Renderscript runtime to render to the framebuffer object instead of the default
- framebuffer by calling <code>rsgBindColorTarget()</code> and passing it the color buffer
- allocation. If applicable, call <code>rsgBindDepthTarget()</code> passing in the depth buffer
- allocation as well.</li>
-
- <li>Render your scene normally with the <code>rsgDraw</code> functions. The scene will be
- rendered into the color buffer instead of the default onscreen framebuffer.</li>
-
- <li>When done, tell the Renderscript runtime stop rendering to the color buffer and back
- to the default framebuffer by calling <code>rsgClearAllRenderTargets()</code>.</li>
-
- <li>Create a fragment shader and bind a the color buffer to it as a texture.</li>
-
- <li>Render your scene to the default framebuffer. The texture will be used according
- to the way you setup your fragment shader.</li>
-</ul>
-
-<p>The following example shows you how to render to a framebuffer object by modifying the
-<a href="{@docRoot}guide/resources/renderscript/Fountain/">Fountain</a> Renderscript sample. The end
-result is the <a href="{@docRoot}guide/resources/renderscript/FountainFBO/">FountainFBO</a> sample.
-The modifications render the exact same scene into a framebuffer object as it does the default
-framebuffer. The framebuffer object is then rendered into the default framebuffer in a small
-area at the top left corner of the screen.</p>
-
-<ol>
- <li>Modify <code>fountain.rs</code> and add the following global variables. This creates setter
- methods when this file is reflected into a <code>.java</code> file, allowing you to allocate
- memory in your Android framework code and binding it to the Renderscript runtime.
-<pre>
-//allocation for color buffer
-rs_allocation gColorBuffer;
-//fragment shader for rendering without a texture (used for rendering to framebuffer object)
-rs_program_fragment gProgramFragment;
-//fragment shader for rendering with a texture (used for rendering to default framebuffer)
-rs_program_fragment gTextureProgramFragment;
-</pre>
- </li>
-
- <li>Modify the root function of <code>fountain.rs</code> to look like the following code. The
- modifications are commented:
-<pre>
-int root() {
- float dt = min(rsGetDt(), 0.1f);
- rsgClearColor(0.f, 0.f, 0.f, 1.f);
- const float height = rsgGetHeight();
- const int size = rsAllocationGetDimX(rsGetAllocation(point));
- float dy2 = dt * (10.f);
- Point_t * p = point;
- for (int ct=0; ct < size; ct++) {
- p->delta.y += dy2;
- p->position += p->delta;
- if ((p->position.y > height) && (p->delta.y > 0)) {
- p->delta.y *= -0.3f;
- }
- p++;
- }
- //Tell Renderscript runtime to render to the frame buffer object
- rsgBindColorTarget(gColorBuffer, 0);
- //Begin rendering on a white background
- rsgClearColor(1.f, 1.f, 1.f, 1.f);
- rsgDrawMesh(partMesh);
-
- //When done, tell Renderscript runtime to stop rendering to framebuffer object
- rsgClearAllRenderTargets();
-
- //Bind a new fragment shader that declares the framebuffer object to be used as a texture
- rsgBindProgramFragment(gTextureProgramFragment);
-
- //Bind the framebuffer object to the fragment shader at slot 0 as a texture
- rsgBindTexture(gTextureProgramFragment, 0, gColorBuffer);
- //Draw a quad using the framebuffer object as the texture
- float startX = 10, startY = 10;
- float s = 256;
- rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
- startX, startY + s, 0, 0, 0,
- startX + s, startY + s, 0, 1, 0,
- startX + s, startY, 0, 1, 1);
-
- //Rebind the original fragment shader to render as normal
- rsgBindProgramFragment(gProgramFragment);
-
- //Render the main scene
- rsgDrawMesh(partMesh);
-
- return 1;
-}
-</pre>
- </li>
-
- <li>In the <code>FountainRS.java</code> file, modify the <code>init()</code> method to look
- like the following code. The modifications are commented:
-
-<pre>
-/* Add necessary members */
-private ScriptC_fountainfbo mScript;
-private Allocation mColorBuffer;
-private ProgramFragment mProgramFragment;
-private ProgramFragment mTextureProgramFragment;
-
-public void init(RenderScriptGL rs, Resources res) {
- mRS = rs;
- mRes = res;
-
- ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
-
- Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
- smb.addVertexAllocation(points.getAllocation());
- smb.addIndexSetType(Mesh.Primitive.POINT);
- Mesh sm = smb.create();
-
- mScript = new ScriptC_fountainfbo(mRS, mRes, R.raw.fountainfbo);
- mScript.set_partMesh(sm);
- mScript.bind_point(points);
-
- ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
- pfb.setVaryingColor(true);
- mProgramFragment = pfb.create();
- mScript.set_gProgramFragment(mProgramFragment);
-
- /* Second fragment shader to use a texture (framebuffer object) to draw with */
- pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
- ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
-
- /* Set the fragment shader in the Renderscript runtime */
- mTextureProgramFragment = pfb.create();
- mScript.set_gTextureProgramFragment(mTextureProgramFragment);
-
- /* Create the allocation for the color buffer */
- Type.Builder colorBuilder = new Type.Builder(mRS, Element.RGBA_8888(mRS));
- colorBuilder.setX(256).setY(256);
- mColorBuffer = Allocation.createTyped(mRS, colorBuilder.create(),
- Allocation.USAGE_GRAPHICS_TEXTURE |
- Allocation.USAGE_GRAPHICS_RENDER_TARGET);
-
- /* Set the allocation in the Renderscript runtime */
- mScript.set_gColorBuffer(mColorBuffer);
-
- mRS.bindRootScript(mScript);
-}
-</pre>
-
-<p class="note"><strong>Note:</strong> This sample doesn't use a depth buffer, but the following code
-shows you how to declare an example depth buffer if you need to use
-one for your application. The depth buffer must have the same dimensions as the color buffer:
-
-<pre>
-Allocation mDepthBuffer;
-
-...
-
-Type.Builder b = new Type.Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16,
- DataKind.PIXEL_DEPTH));
-b.setX(256).setY(256);
-mDepthBuffer = Allocation.createTyped(mRS, b.create(),
-Allocation.USAGE_GRAPHICS_RENDER_TARGET);
-
-</pre>
-</p>
-</li>
-
- <li>Run and use the sample. The smaller, white quad on the top-left corner is using the
- framebuffer object as a texture, which renders the same scene as the main rendering.</li>
-</ol>
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index 42b508b..8b0222a 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -28,6 +28,7 @@
import android.util.TypedValue;
/**
+ * @hide
* @deprecated in API 16
* FileA3D allows users to load Renderscript objects from files
* or resources stored on disk. It could be used to load items
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index 8a49abb..1a8d5bf 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -30,8 +30,9 @@
import android.util.TypedValue;
/**
+ * @hide
* @deprecated in API 16
- * <p>This class gives users a simple way to draw hardware accelerated text.
+ * <p>This class gives users a simple way to draw hardware accelerated text.
* Internally, the glyphs are rendered using the Freetype library and an internal cache of
* rendered glyph bitmaps is maintained. Each font object represents a combination of a typeface,
* and point size. You can create multiple font objects to represent styles such as bold or italic text,
@@ -43,7 +44,7 @@
* render large batches of text in sequence. It is also more efficient to render multiple
* characters at once instead of one by one to improve draw call batching.</p>
* <p>Font color and transparency are not part of the font object and you can freely modify
- * them in the script to suit the user's rendering needs. Font colors work as a state machine.
+ * them in the script to suit the user's rendering needs. Font colors work as a state machine.
* Every new call to draw text uses the last color set in the script.</p>
**/
public class Font extends BaseObj {
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index 7210513..d0d383d 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -21,6 +21,7 @@
import android.util.Log;
/**
+ * @hide
* @deprecated in API 16
* <p>This class is a container for geometric data displayed with
* Renderscript. Internally, a mesh is a collection of allocations that
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index d9f64c6..9bd103e 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -26,6 +26,7 @@
/**
+ * @hide
*
* Program is a base class for all the objects that modify
* various stages of the graphics pipeline
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index 69968ac..dd0f9f5 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -21,6 +21,7 @@
/**
+ * @hide
* @deprecated in API 16
* <p>The Renderscript fragment program, also known as fragment shader is responsible
* for manipulating pixel data in a user defined way. It's constructed from a GLSL
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
index 848c5a3..8ae1777 100644
--- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -21,6 +21,7 @@
/**
+ * @hide
* @deprecated in API 16
* <p>ProgramFragmentFixedFunction is a helper class that provides
* a way to make a simple fragment shader without writing any
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index c44521b..216cb4e 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -21,6 +21,7 @@
/**
+ * @hide
* @deprecated in API 16
* Program raster is primarily used to specify whether point sprites are enabled and to control
* the culling mode. By default, back faces are culled.
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index d0fd6e5..dac9e76 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -21,6 +21,7 @@
/**
+ * @hide
* <p>ProgramStore contains a set of parameters that control how
* the graphics hardware handles writes to the framebuffer.
* It could be used to:</p>
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 2bd5124..50e32f6 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
- /**
+/**
+ * @hide
* <p>The Renderscript vertex program, also known as a vertex shader, describes a stage in
* the graphics pipeline responsible for manipulating geometric data in a user-defined way.
* The object is constructed by providing the Renderscript system with the following data:</p>
@@ -43,6 +44,7 @@
/**
+ * @hide
* @deprecated in API 16
* ProgramVertex, also know as a vertex shader, describes a
* stage in the graphics pipeline responsible for manipulating
@@ -76,14 +78,15 @@
}
/**
- * @deprecated in API 16
- * Builder class for creating ProgramVertex objects.
- * The builder starts empty and the user must minimally provide
- * the GLSL shader code, and the varying inputs. Constant, or
- * uniform parameters to the shader may optionally be provided as
- * well.
- *
- **/
+ * @hide
+ * @deprecated in API 16
+ * Builder class for creating ProgramVertex objects.
+ * The builder starts empty and the user must minimally provide
+ * the GLSL shader code, and the varying inputs. Constant, or
+ * uniform parameters to the shader may optionally be provided as
+ * well.
+ *
+ **/
public static class Builder extends BaseProgramBuilder {
/**
* @deprecated in API 16
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
index 88cade4..ad486f3 100644
--- a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -22,6 +22,7 @@
/**
+ * @hide
* @deprecated in API 16
* ProgramVertexFixedFunction is a helper class that provides a
* simple way to create a fixed function emulation vertex shader
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 82ed95c..3c6c720 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -30,6 +30,7 @@
import android.view.SurfaceView;
/**
+ * @hide
* @deprecated in API 16
* The Surface View for a graphics renderscript (RenderScriptGL) to draw on.
*
diff --git a/graphics/java/android/renderscript/RSTextureView.java b/graphics/java/android/renderscript/RSTextureView.java
index ed04000..7eeeeae 100644
--- a/graphics/java/android/renderscript/RSTextureView.java
+++ b/graphics/java/android/renderscript/RSTextureView.java
@@ -29,6 +29,7 @@
import android.view.TextureView;
/**
+ * @hide
* @deprecated in API 16
* The Texture View for a graphics renderscript (RenderScriptGL)
* to draw on.
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 5269405..52034b1 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -29,6 +29,7 @@
import android.view.SurfaceView;
/**
+ * @hide
* @deprecated in API 16
* The Graphics derivitive of Renderscript. Extends the basic context to add a
* root script which is the display window for graphical output. When the
diff --git a/graphics/java/android/renderscript/package.html b/graphics/java/android/renderscript/package.html
index 5eab23c..eb178c1 100644
--- a/graphics/java/android/renderscript/package.html
+++ b/graphics/java/android/renderscript/package.html
@@ -1,86 +1,10 @@
<HTML>
<BODY>
-<p>The Renderscript rendering and computational APIs offer a low-level, high performance means of
-carrying out mathematical calculations and 3D graphics rendering.</p>
+<p>RenderScript provides support for high-performance computation across heterogeneous processors.</p>
<p>For more information, see the
-<a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
+<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
{@more}
-<p>An example of Renderscript in applications include the 3D carousel view that is present in
-Android 3.0 applications such as the Books and YouTube applications. This API is intended for
-developers who are comfortable working with native code and want to maximize their performance
-critical applications.</p>
-
-<p>Renderscript adopts a control and slave architecture where the low-level native code is controlled by the
-higher level Android system that runs in the virtual machine (VM). The VM code handles resource
-allocation and lifecycle management of the Renderscript enabled application and calls the Renderscript
-code through high level entry points. The Android build tools generate these entry points through reflection on
-the native Renderscript code, which you write in C (C99 standard). The Renderscript code
-does the intensive computation and returns the result back to the Android VM.</p>
-
-<p>You can find the Renderscript native
-APIs in the <code><sdk_root>/platforms/android-11/renderscript</code> directory.
-The Android system APIs are broken into a few main groups:</p>
-
-<h4>Core</h4>
-<p>These classes are used internally by the system for memory allocation. They are used by the classes that
-are generated by the build tools:</p>
-<ul>
- <li>Allocation</li>
- <li>Element</li>
- <li>Type</li>
- <li>Script</li>
-</ul>
-
-
-<h4>Data Types</h4>
-<p>These data types are used by the classes that are generated
-by the build tools. They are the reflected counterparts of the native data types that
-are defined by the native Renderscript APIs and used by your Renderscript code. The
-classes include:</p>
-<ul>
- <li>Byte2, Byte3, and Byte4</li>
- <li>Float2, Float3, Float4</li>
- <li>Int2, Int3, Int4</li>
- <li>Long2, Long3, Long4</li>
- <li>Matrix2f, Matrix3f, Matrix4f</li>
- <li>Short2, Short3, Short4</li>
-</ul>
-
-<p>For example, if you declared the following struct in your .rs Renderscript file:</p>
-
-<pre>struct Hello { float3 position; rs_matrix4x4 transform; }</pre>
-
-<p>The build tools generate a class through reflection that looks like the following:</p>
-<pre>
-class Hello {
- static public class Item {
- Float4 position;
- Matrix4f transform;
- }
-Element createElement(RenderScript rs) {
- Element.Builder eb = new Element.Builder(rs);
- eb.add(Element.F32_3(rs), "position");
- eb.add(Element.MATRIX_4X4(rs), "transform");
- return eb.create();
- }
-}
-</pre>
-
-<h4>Graphics</h4>
-<p>These classes are specific to graphics Renderscripts and support a typical rendering
-pipeline.</p>
-<ul>
-<li>Mesh</li>
-<li>ProgramFragment</li>
-<li>ProgramRaster</li>
-<li>ProgramStore</li>
-<li>ProgramVertex</li>
-<li>RSSurfaceView</li>
-<li>Sampler</li>
-</ul>
-
-</p>
</BODY>
</HTML>
diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h
index 1aecf80..45dc2db 100644
--- a/include/androidfw/InputDevice.h
+++ b/include/androidfw/InputDevice.h
@@ -64,6 +64,7 @@
float max;
float flat;
float fuzz;
+ float resolution;
};
void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier,
@@ -83,7 +84,7 @@
void addSource(uint32_t source);
void addMotionRange(int32_t axis, uint32_t source,
- float min, float max, float flat, float fuzz);
+ float min, float max, float flat, float fuzz, float resolution);
void addMotionRange(const MotionRange& range);
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
diff --git a/include/androidfw/InputTransport.h b/include/androidfw/InputTransport.h
index 5706bce..8712995 100644
--- a/include/androidfw/InputTransport.h
+++ b/include/androidfw/InputTransport.h
@@ -168,6 +168,9 @@
*/
status_t receiveMessage(InputMessage* msg);
+ /* Returns a new object that has a duplicate of this channel's fd. */
+ sp<InputChannel> dup() const;
+
private:
String8 mName;
int mFd;
diff --git a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java b/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
index 83faf35..18225a5 100644
--- a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
@@ -49,8 +49,6 @@
* <p>
* The self-signed certificate may be replaced at a later time by a certificate
* signed by a real Certificate Authority.
- *
- * @hide
*/
public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
private final String mKeystoreAlias;
diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp
index fe891cb..f742052 100644
--- a/libs/androidfw/InputDevice.cpp
+++ b/libs/androidfw/InputDevice.cpp
@@ -172,8 +172,8 @@
}
void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
- float flat, float fuzz) {
- MotionRange range = { axis, source, min, max, flat, fuzz };
+ float flat, float fuzz, float resolution) {
+ MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
mMotionRanges.add(range);
}
diff --git a/libs/androidfw/InputTransport.cpp b/libs/androidfw/InputTransport.cpp
index 351c666..498389e 100644
--- a/libs/androidfw/InputTransport.cpp
+++ b/libs/androidfw/InputTransport.cpp
@@ -219,6 +219,11 @@
return OK;
}
+sp<InputChannel> InputChannel::dup() const {
+ int fd = ::dup(getFd());
+ return fd >= 0 ? new InputChannel(getName(), fd) : NULL;
+}
+
// --- InputPublisher ---
diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp
index e80b325..9bc5c14 100644
--- a/libs/hwui/Dither.cpp
+++ b/libs/hwui/Dither.cpp
@@ -21,38 +21,46 @@
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Must be a power of two
-#define DITHER_KERNEL_SIZE 4
-
-///////////////////////////////////////////////////////////////////////////////
// Lifecycle
///////////////////////////////////////////////////////////////////////////////
void Dither::bindDitherTexture() {
if (!mInitialized) {
- const uint8_t pattern[] = {
- 0, 8, 2, 10,
- 12, 4, 14, 6,
- 3, 11, 1, 9,
- 15, 7, 13, 5
- };
+ bool useFloatTexture = Extensions::getInstance().getMajorGlVersion() >= 3;
glGenTextures(1, &mDitherTexture);
glBindTexture(GL_TEXTURE_2D, mDitherTexture);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE, &pattern);
+ if (useFloatTexture) {
+ float dither = 1.0f / (255.0f * DITHER_KERNEL_SIZE * DITHER_KERNEL_SIZE);
+ const GLfloat pattern[] = {
+ 0 * dither, 8 * dither, 2 * dither, 10 * dither,
+ 12 * dither, 4 * dither, 14 * dither, 6 * dither,
+ 3 * dither, 11 * dither, 1 * dither, 9 * dither,
+ 15 * dither, 7 * dither, 13 * dither, 5 * dither
+ };
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(GLfloat));
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0,
+ GL_RED, GL_FLOAT, &pattern);
+ } else {
+ const uint8_t pattern[] = {
+ 0, 8, 2, 10,
+ 12, 4, 14, 6,
+ 3, 11, 1, 9,
+ 15, 7, 13, 5
+ };
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, &pattern);
+ }
mInitialized = true;
} else {
@@ -76,10 +84,7 @@
bindDitherTexture();
- float ditherSize = 1.0f / DITHER_KERNEL_SIZE;
glUniform1i(program->getUniform("ditherSampler"), textureSlot);
- glUniform1f(program->getUniform("ditherSize"), ditherSize);
- glUniform1f(program->getUniform("ditherSizeSquared"), ditherSize * ditherSize);
}
}; // namespace uirenderer
diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h
index 34cf9bf..4d1f921 100644
--- a/libs/hwui/Dither.h
+++ b/libs/hwui/Dither.h
@@ -17,13 +17,23 @@
#ifndef ANDROID_HWUI_DITHER_H
#define ANDROID_HWUI_DITHER_H
-#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
#include "Program.h"
namespace android {
namespace uirenderer {
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+// Must be a power of two
+#define DITHER_KERNEL_SIZE 4
+// These must not use the .0f notation as they are used from GLSL
+#define DITHER_KERNEL_SIZE_INV (1.0 / 4.0)
+#define DITHER_KERNEL_SIZE_INV_SQUARE (1.0 / 16.0)
+
/**
* Handles dithering for programs.
*/
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index d681609..eef366c 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -27,13 +27,6 @@
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-#define GRADIENT_TEXTURE_HEIGHT 2
-#define GRADIENT_BYTES_PER_PIXEL 4
-
-///////////////////////////////////////////////////////////////////////////////
// Functions
///////////////////////////////////////////////////////////////////////////////
@@ -83,6 +76,10 @@
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
mCache.setOnEntryRemovedListener(this);
+
+ const Extensions& extensions = Extensions::getInstance();
+ mUseFloatTexture = extensions.getMajorGlVersion() >= 3;
+ mHasNpot = extensions.hasNPot();
}
GradientCache::GradientCache(uint32_t maxByteSize):
@@ -120,7 +117,7 @@
void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) {
if (texture) {
- const uint32_t size = texture->width * texture->height * GRADIENT_BYTES_PER_PIXEL;
+ const uint32_t size = texture->width * texture->height * bytesPerPixel();
mSize -= size;
glDeleteTextures(1, &texture->id);
@@ -151,7 +148,7 @@
GradientInfo& info) {
uint32_t width = 256 * (count - 1);
- if (!Extensions::getInstance().hasNPot()) {
+ if (!mHasNpot) {
width = 1 << (31 - __builtin_clz(width));
}
@@ -175,12 +172,12 @@
Texture* texture = new Texture;
texture->width = info.width;
- texture->height = GRADIENT_TEXTURE_HEIGHT;
+ texture->height = 2;
texture->blend = info.hasAlpha;
texture->generation = 1;
// Asume the cache is always big enough
- const uint32_t size = texture->width * texture->height * GRADIENT_BYTES_PER_PIXEL;
+ const uint32_t size = texture->width * texture->height * bytesPerPixel();
while (getSize() + size > mMaxSize) {
mCache.removeOldest();
}
@@ -193,69 +190,110 @@
return texture;
}
+size_t GradientCache::bytesPerPixel() const {
+ // We use 4 channels (RGBA)
+ return 4 * (mUseFloatTexture ? sizeof(float) : sizeof(uint8_t));
+}
+
+void GradientCache::splitToBytes(uint32_t inColor, GradientColor& outColor) const {
+ outColor.r = (inColor >> 16) & 0xff;
+ outColor.g = (inColor >> 8) & 0xff;
+ outColor.b = (inColor >> 0) & 0xff;
+ outColor.a = (inColor >> 24) & 0xff;
+}
+
+void GradientCache::splitToFloats(uint32_t inColor, GradientColor& outColor) const {
+ outColor.r = ((inColor >> 16) & 0xff) / 255.0f;
+ outColor.g = ((inColor >> 8) & 0xff) / 255.0f;
+ outColor.b = ((inColor >> 0) & 0xff) / 255.0f;
+ outColor.a = ((inColor >> 24) & 0xff) / 255.0f;
+}
+
+void GradientCache::mixBytes(GradientColor& start, GradientColor& end, float amount,
+ uint8_t*& dst) const {
+ float oppAmount = 1.0f - amount;
+ const float alpha = start.a * oppAmount + end.a * amount;
+ const float a = alpha / 255.0f;
+
+ *dst++ = uint8_t(a * (start.r * oppAmount + end.r * amount));
+ *dst++ = uint8_t(a * (start.g * oppAmount + end.g * amount));
+ *dst++ = uint8_t(a * (start.b * oppAmount + end.b * amount));
+ *dst++ = uint8_t(alpha);
+}
+
+void GradientCache::mixFloats(GradientColor& start, GradientColor& end, float amount,
+ uint8_t*& dst) const {
+ float oppAmount = 1.0f - amount;
+ const float a = start.a * oppAmount + end.a * amount;
+
+ float* d = (float*) dst;
+ *d++ = a * (start.r * oppAmount + end.r * amount);
+ *d++ = a * (start.g * oppAmount + end.g * amount);
+ *d++ = a * (start.b * oppAmount + end.b * amount);
+ *d++ = a;
+
+ dst += 4 * sizeof(float);
+}
+
void GradientCache::generateTexture(uint32_t* colors, float* positions,
int count, Texture* texture) {
-
const uint32_t width = texture->width;
- const GLsizei rowBytes = width * GRADIENT_BYTES_PER_PIXEL;
- uint32_t pixels[width * texture->height];
+ const GLsizei rowBytes = width * bytesPerPixel();
+ uint8_t pixels[rowBytes * texture->height];
+
+ static ChannelSplitter gSplitters[] = {
+ &android::uirenderer::GradientCache::splitToBytes,
+ &android::uirenderer::GradientCache::splitToFloats,
+ };
+ ChannelSplitter split = gSplitters[mUseFloatTexture];
+
+ static ChannelMixer gMixers[] = {
+ &android::uirenderer::GradientCache::mixBytes,
+ &android::uirenderer::GradientCache::mixFloats,
+ };
+ ChannelMixer mix = gMixers[mUseFloatTexture];
+
+ GradientColor start;
+ (this->*split)(colors[0], start);
+
+ GradientColor end;
+ (this->*split)(colors[1], end);
int currentPos = 1;
+ float startPos = positions[0];
+ float distance = positions[1] - startPos;
- float startA = (colors[0] >> 24) & 0xff;
- float startR = (colors[0] >> 16) & 0xff;
- float startG = (colors[0] >> 8) & 0xff;
- float startB = (colors[0] >> 0) & 0xff;
-
- float endA = (colors[1] >> 24) & 0xff;
- float endR = (colors[1] >> 16) & 0xff;
- float endG = (colors[1] >> 8) & 0xff;
- float endB = (colors[1] >> 0) & 0xff;
-
- float start = positions[0];
- float distance = positions[1] - start;
-
- uint8_t* p = (uint8_t*) pixels;
+ uint8_t* dst = pixels;
for (uint32_t x = 0; x < width; x++) {
float pos = x / float(width - 1);
if (pos > positions[currentPos]) {
- startA = endA;
- startR = endR;
- startG = endG;
- startB = endB;
- start = positions[currentPos];
+ start = end;
+ startPos = positions[currentPos];
currentPos++;
- endA = (colors[currentPos] >> 24) & 0xff;
- endR = (colors[currentPos] >> 16) & 0xff;
- endG = (colors[currentPos] >> 8) & 0xff;
- endB = (colors[currentPos] >> 0) & 0xff;
- distance = positions[currentPos] - start;
+ (this->*split)(colors[currentPos], end);
+ distance = positions[currentPos] - startPos;
}
- float amount = (pos - start) / distance;
- float oppAmount = 1.0f - amount;
-
- const float alpha = startA * oppAmount + endA * amount;
- const float a = alpha / 255.0f;
- *p++ = uint8_t(a * (startR * oppAmount + endR * amount));
- *p++ = uint8_t(a * (startG * oppAmount + endG * amount));
- *p++ = uint8_t(a * (startB * oppAmount + endB * amount));
- *p++ = uint8_t(alpha);
+ float amount = (pos - startPos) / distance;
+ (this->*mix)(start, end, amount, dst);
}
- for (int i = 1; i < GRADIENT_TEXTURE_HEIGHT; i++) {
- memcpy(pixels + width * i, pixels, rowBytes);
- }
+ memcpy(pixels + rowBytes, pixels, rowBytes);
glGenTextures(1, &texture->id);
-
glBindTexture(GL_TEXTURE_2D, texture->id);
- glPixelStorei(GL_UNPACK_ALIGNMENT, GRADIENT_BYTES_PER_PIXEL);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, texture->height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ if (mUseFloatTexture) {
+ // We have to use GL_RGBA16F because GL_RGBA32F does not support filtering
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, texture->height, 0,
+ GL_RGBA, GL_FLOAT, pixels);
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, texture->height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ }
texture->setFilter(GL_LINEAR);
texture->setWrap(GL_CLAMP_TO_EDGE);
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 7dc5b8a..43934d9 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_HWUI_GRADIENT_CACHE_H
#define ANDROID_HWUI_GRADIENT_CACHE_H
-#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
#include <SkShader.h>
@@ -160,12 +160,35 @@
void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);
+ size_t bytesPerPixel() const;
+
+ struct GradientColor {
+ float r;
+ float g;
+ float b;
+ float a;
+ };
+
+ typedef void (GradientCache::*ChannelSplitter)(uint32_t inColor,
+ GradientColor& outColor) const;
+
+ void splitToBytes(uint32_t inColor, GradientColor& outColor) const;
+ void splitToFloats(uint32_t inColor, GradientColor& outColor) const;
+
+ typedef void (GradientCache::*ChannelMixer)(GradientColor& start, GradientColor& end,
+ float amount, uint8_t*& dst) const;
+
+ void mixBytes(GradientColor& start, GradientColor& end, float amount, uint8_t*& dst) const;
+ void mixFloats(GradientColor& start, GradientColor& end, float amount, uint8_t*& dst) const;
+
LruCache<GradientCacheEntry, Texture*> mCache;
uint32_t mSize;
uint32_t mMaxSize;
GLint mMaxTextureSize;
+ bool mUseFloatTexture;
+ bool mHasNpot;
Vector<SkShader*> mGarbage;
mutable Mutex mLock;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index f78fb2d..2479630 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -19,6 +19,7 @@
#include <utils/String8.h>
#include "Caches.h"
+#include "Dither.h"
#include "ProgramCache.h"
namespace android {
@@ -32,6 +33,9 @@
#define MODULATE_OP_MODULATE 1
#define MODULATE_OP_MODULATE_A8 2
+#define STR(x) STR1(x)
+#define STR1(x) #x
+
///////////////////////////////////////////////////////////////////////////////
// Vertex shaders snippets
///////////////////////////////////////////////////////////////////////////////
@@ -51,17 +55,8 @@
"uniform mat4 transform;\n";
const char* gVS_Header_Uniforms_IsPoint =
"uniform mediump float pointSize;\n";
-const char* gVS_Header_Uniforms_HasGradient[3] = {
- // Linear
- "uniform mat4 screenSpace;\n"
- "uniform float ditherSize;\n",
- // Circular
- "uniform mat4 screenSpace;\n"
- "uniform float ditherSize;\n",
- // Sweep
- "uniform mat4 screenSpace;\n"
- "uniform float ditherSize;\n"
-};
+const char* gVS_Header_Uniforms_HasGradient =
+ "uniform mat4 screenSpace;\n";
const char* gVS_Header_Uniforms_HasBitmap =
"uniform mat4 textureTransform;\n"
"uniform mediump vec2 textureDimension;\n";
@@ -105,21 +100,21 @@
const char* gVS_Main_OutGradient[6] = {
// Linear
" linear = vec2((screenSpace * position).x, 0.5);\n"
- " ditherTexCoords = (transform * position).xy * ditherSize;\n",
+ " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n",
" linear = (screenSpace * position).x;\n"
- " ditherTexCoords = (transform * position).xy * ditherSize;\n",
+ " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n",
// Circular
" circular = (screenSpace * position).xy;\n"
- " ditherTexCoords = (transform * position).xy * ditherSize;\n",
+ " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n",
" circular = (screenSpace * position).xy;\n"
- " ditherTexCoords = (transform * position).xy * ditherSize;\n",
+ " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n",
// Sweep
" sweep = (screenSpace * position).xy;\n"
- " ditherTexCoords = (transform * position).xy * ditherSize;\n",
+ " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n",
" sweep = (screenSpace * position).xy;\n"
- " ditherTexCoords = (transform * position).xy * ditherSize;\n",
+ " ditherTexCoords = (transform * position).xy * " STR(DITHER_KERNEL_SIZE_INV) ";\n",
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
@@ -153,24 +148,14 @@
"uniform sampler2D baseSampler;\n";
const char* gFS_Uniforms_ExternalTextureSampler =
"uniform samplerExternalOES baseSampler;\n";
-#define FS_UNIFORMS_DITHER \
- "uniform float ditherSizeSquared;\n" \
- "uniform sampler2D ditherSampler;\n"
-#define FS_UNIFORMS_GRADIENT \
- "uniform vec4 startColor;\n" \
+const char* gFS_Uniforms_Dither =
+ "uniform sampler2D ditherSampler;";
+const char* gFS_Uniforms_GradientSampler[2] = {
+ "%s\n"
+ "uniform sampler2D gradientSampler;\n",
+ "%s\n"
+ "uniform vec4 startColor;\n"
"uniform vec4 endColor;\n"
-const char* gFS_Uniforms_GradientSampler[6] = {
- // Linear
- FS_UNIFORMS_DITHER "uniform sampler2D gradientSampler;\n",
- FS_UNIFORMS_DITHER FS_UNIFORMS_GRADIENT,
-
- // Circular
- FS_UNIFORMS_DITHER "uniform sampler2D gradientSampler;\n",
- FS_UNIFORMS_DITHER FS_UNIFORMS_GRADIENT,
-
- // Sweep
- FS_UNIFORMS_DITHER "uniform sampler2D gradientSampler;\n",
- FS_UNIFORMS_DITHER FS_UNIFORMS_GRADIENT
};
const char* gFS_Uniforms_BitmapSampler =
"uniform sampler2D bitmapSampler;\n";
@@ -197,10 +182,14 @@
" highp vec2 outBitmapTexCoords = outPointBitmapTexCoords + "
"((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
-#define FS_MAIN_DITHER \
- "texture2D(ditherSampler, ditherTexCoords).a * ditherSizeSquared"
+const char* gFS_Main_Dither[2] = {
+ // ES 2.0
+ "texture2D(ditherSampler, ditherTexCoords).a * " STR(DITHER_KERNEL_SIZE_INV_SQUARE),
+ // ES 3.0
+ "texture2D(ditherSampler, ditherTexCoords).r"
+};
const char* gFS_Main_AddDitherToGradient =
- " gradientColor += " FS_MAIN_DITHER ";\n";
+ " gradientColor += %s;\n";
// Fast cases
const char* gFS_Fast_SingleColor =
@@ -233,18 +222,18 @@
"}\n\n";
const char* gFS_Fast_SingleGradient[2] = {
"\nvoid main(void) {\n"
- " gl_FragColor = " FS_MAIN_DITHER " + texture2D(gradientSampler, linear);\n"
+ " gl_FragColor = %s + texture2D(gradientSampler, linear);\n"
"}\n\n",
"\nvoid main(void) {\n"
- " gl_FragColor = " FS_MAIN_DITHER " + mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n"
- "}\n\n"
+ " gl_FragColor = %s + mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n"
+ "}\n\n",
};
const char* gFS_Fast_SingleModulateGradient[2] = {
"\nvoid main(void) {\n"
- " gl_FragColor = " FS_MAIN_DITHER " + color.a * texture2D(gradientSampler, linear);\n"
+ " gl_FragColor = %s + color.a * texture2D(gradientSampler, linear);\n"
"}\n\n",
"\nvoid main(void) {\n"
- " gl_FragColor = " FS_MAIN_DITHER " + color.a * mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n"
+ " gl_FragColor = %s + color.a * mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n"
"}\n\n"
};
@@ -410,7 +399,7 @@
// Constructors/destructors
///////////////////////////////////////////////////////////////////////////////
-ProgramCache::ProgramCache() {
+ProgramCache::ProgramCache(): mHasES3(Extensions::getInstance().getMajorGlVersion() >= 3) {
}
ProgramCache::~ProgramCache() {
@@ -484,7 +473,7 @@
shader.append(gVS_Header_Uniforms_TextureTransform);
}
if (description.hasGradient) {
- shader.append(gVS_Header_Uniforms_HasGradient[description.gradientType]);
+ shader.append(gVS_Header_Uniforms_HasGradient);
}
if (description.hasBitmap) {
shader.append(gVS_Header_Uniforms_HasBitmap);
@@ -601,7 +590,8 @@
shader.append(gFS_Uniforms_ExternalTextureSampler);
}
if (description.hasGradient) {
- shader.append(gFS_Uniforms_GradientSampler[gradientIndex(description)]);
+ shader.appendFormat(gFS_Uniforms_GradientSampler[description.isSimpleGradient],
+ gFS_Uniforms_Dither);
}
if (description.hasBitmap && description.isPoint) {
shader.append(gFS_Header_Uniforms_PointHasBitmap);
@@ -652,9 +642,11 @@
fast = true;
} else if (singleGradient) {
if (!description.modulate) {
- shader.append(gFS_Fast_SingleGradient[description.isSimpleGradient]);
+ shader.appendFormat(gFS_Fast_SingleGradient[description.isSimpleGradient],
+ gFS_Main_Dither[mHasES3]);
} else {
- shader.append(gFS_Fast_SingleModulateGradient[description.isSimpleGradient]);
+ shader.appendFormat(gFS_Fast_SingleModulateGradient[description.isSimpleGradient],
+ gFS_Main_Dither[mHasES3]);
}
fast = true;
}
@@ -708,7 +700,7 @@
}
if (description.hasGradient) {
shader.append(gFS_Main_FetchGradient[gradientIndex(description)]);
- shader.append(gFS_Main_AddDitherToGradient);
+ shader.appendFormat(gFS_Main_AddDitherToGradient, gFS_Main_Dither[mHasES3]);
}
if (description.hasBitmap) {
if (description.isPoint) {
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 1ca148d..38f6f99 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -57,6 +57,8 @@
void printLongString(const String8& shader) const;
KeyedVector<programid, Program*> mCache;
+
+ const bool mHasES3;
}; // class ProgramCache
}; // namespace uirenderer
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b80a166..917a47d 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -50,6 +50,7 @@
private long mVolumeKeyUpTime;
private final boolean mUseMasterVolume;
private final boolean mUseVolumeKeySounds;
+ private final Binder mToken = new Binder();
private static String TAG = "AudioManager";
/**
@@ -2075,7 +2076,8 @@
IAudioService service = getService();
try {
// pi != null
- service.registerMediaButtonIntent(pi, eventReceiver);
+ service.registerMediaButtonIntent(pi, eventReceiver,
+ eventReceiver == null ? mToken : null);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerMediaButtonIntent"+e);
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index fd71d79..773d7b6 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -357,7 +357,7 @@
private static final int SCO_STATE_INACTIVE = 0;
// SCO audio activation request waiting for headset service to connect
private static final int SCO_STATE_ACTIVATE_REQ = 1;
- // SCO audio state is active or starting due to a local request to start a virtual call
+ // SCO audio state is active or starting due to a request from AudioManager API
private static final int SCO_STATE_ACTIVE_INTERNAL = 3;
// SCO audio deactivation request waiting for headset service to connect
private static final int SCO_STATE_DEACTIVATE_REQ = 5;
@@ -530,6 +530,9 @@
// Register for package removal intent broadcasts for media button receiver persistence
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
pkgFilter.addDataScheme("package");
context.registerReceiver(mReceiver, pkgFilter);
@@ -2053,8 +2056,7 @@
mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
if (mScoAudioState == SCO_STATE_INACTIVE) {
if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (mBluetoothHeadset.startScoUsingVirtualVoiceCall(
- mBluetoothHeadsetDevice)) {
+ if (mBluetoothHeadset.connectAudio()) {
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
} else {
broadcastScoConnectionState(
@@ -2076,8 +2078,7 @@
mScoAudioState == SCO_STATE_ACTIVATE_REQ)) {
if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) {
if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
- if (!mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
- mBluetoothHeadsetDevice)) {
+ if (!mBluetoothHeadset.disconnectAudio()) {
mScoAudioState = SCO_STATE_INACTIVE;
broadcastScoConnectionState(
AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -2250,12 +2251,10 @@
switch (mScoAudioState) {
case SCO_STATE_ACTIVATE_REQ:
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
- status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
- mBluetoothHeadsetDevice);
+ status = mBluetoothHeadset.connectAudio();
break;
case SCO_STATE_DEACTIVATE_REQ:
- status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
- mBluetoothHeadsetDevice);
+ status = mBluetoothHeadset.disconnectAudio();
break;
case SCO_STATE_DEACTIVATE_EXT_REQ:
status = mBluetoothHeadset.stopVoiceRecognition(
@@ -4037,14 +4036,21 @@
0,
null,
SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
- } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
+ } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+ || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) {
if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
// a package is being removed, not replaced
String packageName = intent.getData().getSchemeSpecificPart();
if (packageName != null) {
- removeMediaButtonReceiverForPackage(packageName);
+ cleanupMediaButtonReceiverForPackage(packageName, true);
}
}
+ } else if (action.equals(Intent.ACTION_PACKAGE_ADDED)
+ || action.equals(Intent.ACTION_PACKAGE_CHANGED)) {
+ String packageName = intent.getData().getSchemeSpecificPart();
+ if (packageName != null) {
+ cleanupMediaButtonReceiverForPackage(packageName, false);
+ }
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
AudioSystem.setParameters("screen_state=on");
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
@@ -4851,8 +4857,9 @@
}
}
- private static class RemoteControlStackEntry {
+ private static class RemoteControlStackEntry implements DeathRecipient {
public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+ final public AudioService mService;
/**
* The target for the ACTION_MEDIA_BUTTON events.
* Always non null.
@@ -4863,6 +4870,7 @@
* Always non null.
*/
final public ComponentName mReceiverComponent;
+ public IBinder mToken;
public String mCallingPackageName;
public int mCallingUid;
/**
@@ -4893,9 +4901,12 @@
}
/** precondition: mediaIntent != null */
- public RemoteControlStackEntry(PendingIntent mediaIntent, ComponentName eventReceiver) {
+ public RemoteControlStackEntry(AudioService service, PendingIntent mediaIntent,
+ ComponentName eventReceiver, IBinder token) {
+ mService = service;
mMediaIntent = mediaIntent;
mReceiverComponent = eventReceiver;
+ mToken = token;
mCallingUid = -1;
mRcClient = null;
mRccId = ++sLastRccId;
@@ -4905,6 +4916,17 @@
RemoteControlClient.PLAYBACK_SPEED_1X);
resetPlaybackInfo();
+ if (mToken != null) {
+ try {
+ mToken.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ mService.mAudioHandler.post(new Runnable() {
+ @Override public void run() {
+ mService.unregisterMediaButtonIntent(mMediaIntent);
+ }
+ });
+ }
+ }
}
public void unlinkToRcClientDeath() {
@@ -4920,9 +4942,22 @@
}
}
+ public void destroy() {
+ unlinkToRcClientDeath();
+ if (mToken != null) {
+ mToken.unlinkToDeath(this, 0);
+ mToken = null;
+ }
+ }
+
+ @Override
+ public void binderDied() {
+ mService.unregisterMediaButtonIntent(mMediaIntent);
+ }
+
@Override
protected void finalize() throws Throwable {
- unlinkToRcClientDeath();// unlink exception handled inside method
+ destroy(); // unlink exception handled inside method
super.finalize();
}
}
@@ -5021,11 +5056,12 @@
* Remove any entry in the remote control stack that has the same package name as packageName
* Pre-condition: packageName != null
*/
- private void removeMediaButtonReceiverForPackage(String packageName) {
+ private void cleanupMediaButtonReceiverForPackage(String packageName, boolean removeAll) {
synchronized(mRCStack) {
if (mRCStack.empty()) {
return;
} else {
+ final PackageManager pm = mContext.getPackageManager();
RemoteControlStackEntry oldTop = mRCStack.peek();
Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
// iterate over the stack entries
@@ -5033,10 +5069,19 @@
// evaluated it, traversal order doesn't matter here)
while(stackIterator.hasNext()) {
RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
- if (packageName.equals(rcse.mMediaIntent.getCreatorPackage())) {
+ if (removeAll && packageName.equals(rcse.mMediaIntent.getCreatorPackage())) {
// a stack entry is from the package being removed, remove it from the stack
stackIterator.remove();
- rcse.unlinkToRcClientDeath();
+ rcse.destroy();
+ } else if (rcse.mReceiverComponent != null) {
+ try {
+ // Check to see if this receiver still exists.
+ pm.getReceiverInfo(rcse.mReceiverComponent, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ // Not found -- remove it!
+ stackIterator.remove();
+ rcse.destroy();
+ }
}
}
if (mRCStack.empty()) {
@@ -5079,7 +5124,7 @@
mediaButtonIntent.setComponent(eventReceiver);
PendingIntent pi = PendingIntent.getBroadcast(mContext,
0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
- registerMediaButtonIntent(pi, eventReceiver);
+ registerMediaButtonIntent(pi, eventReceiver, null);
}
}
@@ -5089,7 +5134,8 @@
* Called synchronized on mAudioFocusLock, then mRCStack
* precondition: mediaIntent != null
*/
- private void pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent, ComponentName target) {
+ private void pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent, ComponentName target,
+ IBinder token) {
// already at top of stack?
if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(mediaIntent)) {
return;
@@ -5111,7 +5157,7 @@
Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
}
if (!wasInsideStack) {
- rcse = new RemoteControlStackEntry(mediaIntent, target);
+ rcse = new RemoteControlStackEntry(this, mediaIntent, target, token);
}
mRCStack.push(rcse); // rcse is never null
@@ -5133,7 +5179,7 @@
for (int index = mRCStack.size()-1; index >= 0; index--) {
final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
if (rcse.mMediaIntent.equals(pi)) {
- rcse.unlinkToRcClientDeath();
+ rcse.destroy();
// ok to remove element while traversing the stack since we're leaving the loop
mRCStack.removeElementAt(index);
break;
@@ -5421,12 +5467,13 @@
* see AudioManager.registerMediaButtonIntent(PendingIntent pi, ComponentName c)
* precondition: mediaIntent != null
*/
- public void registerMediaButtonIntent(PendingIntent mediaIntent, ComponentName eventReceiver) {
+ public void registerMediaButtonIntent(PendingIntent mediaIntent, ComponentName eventReceiver,
+ IBinder token) {
Log.i(TAG, " Remote Control registerMediaButtonIntent() for " + mediaIntent);
synchronized(mAudioFocusLock) {
synchronized(mRCStack) {
- pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver);
+ pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token);
// new RC client, assume every type of information shall be queried
checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 25aae8f..13f6c02 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -120,7 +120,7 @@
oneway void dispatchMediaKeyEvent(in KeyEvent keyEvent);
void dispatchMediaKeyEventUnderWakelock(in KeyEvent keyEvent);
- void registerMediaButtonIntent(in PendingIntent pi, in ComponentName c);
+ void registerMediaButtonIntent(in PendingIntent pi, in ComponentName c, IBinder token);
oneway void unregisterMediaButtonIntent(in PendingIntent pi);
oneway void registerMediaButtonEventReceiverForCalls(in ComponentName c);
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 1f5ca35..c0fbd2e 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -257,8 +257,10 @@
}
/**
- * Writes an encoded sample into the muxer. The application needs to make
- * sure that the samples are written into the right tracks.
+ * Writes an encoded sample into the muxer.
+ * <p>The application needs to make sure that the samples are written into
+ * the right tracks. Also, it needs to make sure the samples for each track
+ * are written in chronological order.</p>
* @param byteBuf The encoded sample.
* @param trackIndex The track index for this sample.
* @param bufferInfo The buffer information related to this sample.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7bdcf6e..5b911c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -17,11 +17,11 @@
package com.android.systemui.statusbar;
+import android.service.notification.StatusBarNotification;
import android.content.res.Configuration;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.internal.widget.SizeAdaptiveLayout;
import com.android.systemui.R;
import com.android.systemui.SearchPanelView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 752bb0c..cbbaab3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -20,10 +20,10 @@
import android.os.IBinder;
import android.os.Message;
+import android.service.notification.StatusBarNotification;
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
-import com.android.internal.statusbar.StatusBarNotification;
/**
* This class takes the functions from IStatusBar that come in on
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c82f250..886ed77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -16,12 +16,11 @@
package com.android.systemui.statusbar;
-import android.app.Notification;
+import android.service.notification.StatusBarNotification;
import android.os.IBinder;
import android.view.View;
import android.widget.ImageView;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
import java.util.Comparator;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9f54573..c2dc159 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -26,6 +26,7 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
+import android.service.notification.StatusBarNotification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -76,7 +77,6 @@
import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -708,6 +708,7 @@
private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
public void onClick(View v) {
+ awakenDreams();
toggleRecentApps();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index ecc70d6..976dd01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import android.service.notification.StatusBarNotification;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
@@ -23,10 +24,7 @@
import android.text.StaticLayout;
import android.text.Layout.Alignment;
import android.text.TextPaint;
-import android.text.TextUtils;
-import android.util.Slog;
import android.view.View;
-import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextSwitcher;
import android.widget.TextView;
@@ -35,7 +33,6 @@
import java.util.ArrayList;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.internal.util.CharSequences;
import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 0944b40..68d048d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -28,16 +28,11 @@
import android.location.LocationManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.util.Slog;
-import android.view.View;
-import android.widget.ImageView;
// private NM API
import android.app.INotificationManager;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
public class LocationController extends BroadcastReceiver {
private static final String TAG = "StatusBar.LocationController";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 3d6bfe7..05bba89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -23,6 +23,7 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
+import android.service.notification.StatusBarNotification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -58,7 +59,6 @@
import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 0859874..725d9e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -21,9 +21,9 @@
import android.animation.LayoutTransition;
import android.app.Notification;
import android.app.PendingIntent;
+import android.service.notification.StatusBarNotification;
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.os.Handler;
@@ -37,11 +37,9 @@
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.R;
import com.android.systemui.statusbar.StatusBarIconView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 413cc78..dc5de02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -16,8 +16,8 @@
package com.android.systemui.statusbar.tv;
+import android.service.notification.StatusBarNotification;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.systemui.statusbar.BaseStatusBar;
import android.os.IBinder;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 49460de..5f9e921 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -59,6 +59,8 @@
import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.Settings;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -1801,7 +1803,23 @@
? com.android.internal.R.anim.lock_screen_wallpaper_behind_enter
: com.android.internal.R.anim.lock_screen_behind_enter);
}
-
+
+ private static void awakenDreams() {
+ IDreamManager dreamManager = getDreamManager();
+ if (dreamManager != null) {
+ try {
+ dreamManager.awaken();
+ } catch (RemoteException e) {
+ // fine, stay asleep then
+ }
+ }
+ }
+
+ static IDreamManager getDreamManager() {
+ return IDreamManager.Stub.asInterface(
+ ServiceManager.checkService(DreamService.DREAM_SERVICE));
+ }
+
static ITelephony getTelephonyService() {
return ITelephony.Stub.asInterface(
ServiceManager.checkService(Context.TELEPHONY_SERVICE));
@@ -4550,6 +4568,7 @@
}
void startDockOrHome() {
+ awakenDreams();
// We don't have dock home anymore. Home is home. If you lived here, you'd be home by now.
mContext.startActivityAsUser(mHomeIntent, UserHandle.CURRENT);
}
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 43d76bb..602afd4 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -882,8 +882,9 @@
snprintf(name, sizeof(name), "%d", range.axis);
}
dump.appendFormat(INDENT3 "%s: source=0x%08x, "
- "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
- name, range.source, range.min, range.max, range.flat, range.fuzz);
+ "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
+ name, range.source, range.min, range.max, range.flat, range.fuzz,
+ range.resolution);
}
}
@@ -2247,20 +2248,20 @@
if (mParameters.mode == Parameters::MODE_POINTER) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
}
} else {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
}
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
if (mCursorScrollAccumulator.haveRelativeVWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
}
if (mCursorScrollAccumulator.haveRelativeHWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
}
}
@@ -2611,10 +2612,12 @@
}
if (mCursorScrollAccumulator.haveRelativeVWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f);
}
if (mCursorScrollAccumulator.haveRelativeHWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f);
}
}
}
@@ -3063,6 +3066,7 @@
mOrientedRanges.touchMajor.max = diagonalSize;
mOrientedRanges.touchMajor.flat = 0;
mOrientedRanges.touchMajor.fuzz = 0;
+ mOrientedRanges.touchMajor.resolution = 0;
mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
@@ -3073,6 +3077,7 @@
mOrientedRanges.toolMajor.max = diagonalSize;
mOrientedRanges.toolMajor.flat = 0;
mOrientedRanges.toolMajor.fuzz = 0;
+ mOrientedRanges.toolMajor.resolution = 0;
mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
@@ -3083,6 +3088,7 @@
mOrientedRanges.size.max = 1.0;
mOrientedRanges.size.flat = 0;
mOrientedRanges.size.fuzz = 0;
+ mOrientedRanges.size.resolution = 0;
} else {
mSizeScale = 0.0f;
}
@@ -3106,6 +3112,7 @@
mOrientedRanges.pressure.max = 1.0;
mOrientedRanges.pressure.flat = 0;
mOrientedRanges.pressure.fuzz = 0;
+ mOrientedRanges.pressure.resolution = 0;
// Tilt
mTiltXCenter = 0;
@@ -3129,6 +3136,7 @@
mOrientedRanges.tilt.max = M_PI_2;
mOrientedRanges.tilt.flat = 0;
mOrientedRanges.tilt.fuzz = 0;
+ mOrientedRanges.tilt.resolution = 0;
}
// Orientation
@@ -3142,6 +3150,7 @@
mOrientedRanges.orientation.max = M_PI;
mOrientedRanges.orientation.flat = 0;
mOrientedRanges.orientation.fuzz = 0;
+ mOrientedRanges.orientation.resolution = 0;
} else if (mCalibration.orientationCalibration !=
Calibration::ORIENTATION_CALIBRATION_NONE) {
if (mCalibration.orientationCalibration
@@ -3165,6 +3174,7 @@
mOrientedRanges.orientation.max = M_PI_2;
mOrientedRanges.orientation.flat = 0;
mOrientedRanges.orientation.fuzz = 0;
+ mOrientedRanges.orientation.resolution = 0;
}
// Distance
@@ -3190,6 +3200,7 @@
mOrientedRanges.distance.flat = 0;
mOrientedRanges.distance.fuzz =
mRawPointerAxes.distance.fuzz * mDistanceScale;
+ mOrientedRanges.distance.resolution = 0;
}
// Compute oriented precision, scales and ranges.
@@ -3204,12 +3215,14 @@
mOrientedRanges.x.min = mYTranslate;
mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
mOrientedRanges.x.flat = 0;
- mOrientedRanges.x.fuzz = mYScale;
+ mOrientedRanges.x.fuzz = 0;
+ mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
mOrientedRanges.y.min = mXTranslate;
mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
mOrientedRanges.y.flat = 0;
- mOrientedRanges.y.fuzz = mXScale;
+ mOrientedRanges.y.fuzz = 0;
+ mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
break;
default:
@@ -3219,12 +3232,14 @@
mOrientedRanges.x.min = mXTranslate;
mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
mOrientedRanges.x.flat = 0;
- mOrientedRanges.x.fuzz = mXScale;
+ mOrientedRanges.x.fuzz = 0;
+ mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
mOrientedRanges.y.min = mYTranslate;
mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
mOrientedRanges.y.flat = 0;
- mOrientedRanges.y.fuzz = mYScale;
+ mOrientedRanges.y.fuzz = 0;
+ mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
break;
}
@@ -6045,10 +6060,10 @@
for (size_t i = 0; i < mAxes.size(); i++) {
const Axis& axis = mAxes.valueAt(i);
info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK,
- axis.min, axis.max, axis.flat, axis.fuzz);
+ axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK,
- axis.min, axis.max, axis.flat, axis.fuzz);
+ axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
}
}
}
@@ -6078,8 +6093,8 @@
dump.append(" (invert)");
}
- dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n",
- axis.min, axis.max, axis.flat, axis.fuzz);
+ dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
+ axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, "
"highScale=%0.5f, highOffset=%0.5f\n",
axis.scale, axis.offset, axis.highScale, axis.highOffset);
@@ -6125,18 +6140,21 @@
float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
scale, 0.0f, highScale, 0.0f,
- 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
+ rawAxisInfo.resolution * scale);
} else if (isCenteredAxis(axisInfo.axis)) {
float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
scale, offset, scale, offset,
- -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
+ rawAxisInfo.resolution * scale);
} else {
float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
scale, 0.0f, scale, 0.0f,
- 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
+ rawAxisInfo.resolution * scale);
}
// To eliminate noise while the joystick is at rest, filter out small variations
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index c596b37..8a52c06 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -1730,10 +1730,11 @@
float highScale; // scale factor from raw to normalized values of high split
float highOffset; // offset to add after scaling for normalization of high split
- float min; // normalized inclusive minimum
- float max; // normalized inclusive maximum
- float flat; // normalized flat region size
- float fuzz; // normalized error tolerance
+ float min; // normalized inclusive minimum
+ float max; // normalized inclusive maximum
+ float flat; // normalized flat region size
+ float fuzz; // normalized error tolerance
+ float resolution; // normalized resolution in units/mm
float filter; // filter out small variations of this size
float currentValue; // current value
@@ -1744,7 +1745,7 @@
void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
bool explicitlyMapped, float scale, float offset,
float highScale, float highOffset,
- float min, float max, float flat, float fuzz) {
+ float min, float max, float flat, float fuzz, float resolution) {
this->rawAxisInfo = rawAxisInfo;
this->axisInfo = axisInfo;
this->explicitlyMapped = explicitlyMapped;
@@ -1756,6 +1757,7 @@
this->max = max;
this->flat = flat;
this->fuzz = fuzz;
+ this->resolution = resolution;
this->filter = 0;
resetValue();
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 3b541ec..a28c387 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1070,7 +1070,8 @@
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
showCurrentInputLocked(getAppShowFlags(), null);
}
- return new InputBindResult(session.session, session.channel, mCurId, mCurSeq);
+ return new InputBindResult(session.session,
+ session.channel != null ? session.channel.dup() : null, mCurId, mCurSeq);
}
InputBindResult startInputLocked(IInputMethodClient client,
@@ -2357,13 +2358,15 @@
return true;
case MSG_CREATE_SESSION: {
args = (SomeArgs)msg.obj;
+ IInputMethod method = (IInputMethod)args.arg1;
InputChannel channel = (InputChannel)args.arg2;
try {
- ((IInputMethod)args.arg1).createSession(channel,
- (IInputSessionCallback)args.arg3);
+ method.createSession(channel, (IInputSessionCallback)args.arg3);
} catch (RemoteException e) {
} finally {
- if (channel != null) {
+ // Dispose the channel if the input method is not local to this process
+ // because the remote proxy will get its own copy when unparceled.
+ if (channel != null && Binder.isProxy(method)) {
channel.dispose();
}
}
@@ -2404,16 +2407,24 @@
// There is nothing interesting about the last client dying.
}
return true;
- case MSG_BIND_METHOD:
+ case MSG_BIND_METHOD: {
args = (SomeArgs)msg.obj;
+ IInputMethodClient client = (IInputMethodClient)args.arg1;
+ InputBindResult res = (InputBindResult)args.arg2;
try {
- ((IInputMethodClient)args.arg1).onBindMethod(
- (InputBindResult)args.arg2);
+ client.onBindMethod(res);
} catch (RemoteException e) {
Slog.w(TAG, "Client died receiving input method " + args.arg2);
+ } finally {
+ // Dispose the channel if the input method is not local to this process
+ // because the remote proxy will get its own copy when unparceled.
+ if (res.channel != null && Binder.isProxy(client)) {
+ res.channel.dispose();
+ }
}
args.recycle();
return true;
+ }
case MSG_SET_ACTIVE:
try {
((ClientState)msg.obj).client.setActive(msg.arg1 != 0);
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 44d730c..cfb892f 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -26,16 +26,17 @@
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
-import android.app.INotificationListener;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -57,6 +58,9 @@
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
+import android.service.notification.INotificationListener;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.AtomicFile;
@@ -68,8 +72,6 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
-import com.android.internal.statusbar.StatusBarNotification;
-
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -121,6 +123,8 @@
private static final boolean ENABLE_BLOCKED_NOTIFICATIONS = true;
private static final boolean ENABLE_BLOCKED_TOASTS = true;
+ private static final String ENABLED_NOTIFICATION_LISTENERS_SEPARATOR = ":";
+
final Context mContext;
final IActivityManager mAm;
final UserManager mUserManager;
@@ -163,8 +167,18 @@
private final AppOpsManager mAppOps;
- private ArrayList<NotificationListenerInfo> mListeners = new ArrayList<NotificationListenerInfo>();
- private ArrayList<String> mEnabledListenersForCurrentUser = new ArrayList<String>();
+ // contains connections to all connected listeners, including app services
+ // and system listeners
+ private ArrayList<NotificationListenerInfo> mListeners
+ = new ArrayList<NotificationListenerInfo>();
+ // things that will be put into mListeners as soon as they're ready
+ private ArrayList<String> mServicesBinding = new ArrayList<String>();
+ // lists the component names of all enabled (and therefore connected) listener
+ // app services for the current user only
+ private HashSet<ComponentName> mEnabledListenersForCurrentUser
+ = new HashSet<ComponentName>();
+ // Just the packages from mEnabledListenersForCurrentUser
+ private HashSet<String> mEnabledListenerPackageNames = new HashSet<String>();
// Notification control database. For now just contains disabled packages.
private AtomicFile mPolicyFile;
@@ -181,27 +195,42 @@
private class NotificationListenerInfo implements DeathRecipient {
INotificationListener listener;
- String pkg;
+ ComponentName component;
int userid;
boolean isSystem;
+ ServiceConnection connection;
- public NotificationListenerInfo(INotificationListener listener, String pkg, int userid,
- boolean isSystem) {
+ public NotificationListenerInfo(INotificationListener listener, ComponentName component,
+ int userid, boolean isSystem) {
this.listener = listener;
- this.pkg = pkg;
+ this.component = component;
this.userid = userid;
this.isSystem = isSystem;
+ this.connection = null;
+ }
+
+ public NotificationListenerInfo(INotificationListener listener, ComponentName component,
+ int userid, ServiceConnection connection) {
+ this.listener = listener;
+ this.component = component;
+ this.userid = userid;
+ this.isSystem = false;
+ this.connection = connection;
}
boolean enabledAndUserMatches(StatusBarNotification sbn) {
final int nid = sbn.getUserId();
- if (!(isSystem || isEnabledForUser(nid))) return false;
+ if (!isEnabledForCurrentUser()) {
+ return false;
+ }
if (this.userid == UserHandle.USER_ALL) return true;
return (nid == UserHandle.USER_ALL || nid == this.userid);
}
public void notifyPostedIfUserMatch(StatusBarNotification sbn) {
- if (!enabledAndUserMatches(sbn)) return;
+ if (!enabledAndUserMatches(sbn)) {
+ return;
+ }
try {
listener.onNotificationPosted(sbn);
} catch (RemoteException ex) {
@@ -220,15 +249,17 @@
@Override
public void binderDied() {
- unregisterListener(this.listener, this.userid);
+ if (connection == null) {
+ // This is not a service; it won't be recreated. We can give up this connection.
+ unregisterListener(this.listener, this.userid);
+ }
}
/** convenience method for looking in mEnabledListenersForCurrentUser */
- public boolean isEnabledForUser(int userid) {
- for (int i=0; i<mEnabledListenersForCurrentUser.size(); i++) {
- if (this.pkg.equals(mEnabledListenersForCurrentUser.get(i))) return true;
- }
- return false;
+ public boolean isEnabledForCurrentUser() {
+ if (this.isSystem) return true;
+ if (this.connection == null) return false;
+ return mEnabledListenersForCurrentUser.contains(this.component);
}
}
@@ -434,6 +465,12 @@
}
}
+ /**
+ * System-only API for getting a list of current (i.e. not cleared) notifications.
+ *
+ * Requires ACCESS_NOTIFICATIONS which is signature|system.
+ */
+ @Override
public StatusBarNotification[] getActiveNotifications(String callingPkg) {
// enforce() will ensure the calling uid has the correct permission
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NOTIFICATIONS,
@@ -456,6 +493,12 @@
return tmp;
}
+ /**
+ * System-only API for getting a list of recent (cleared, no longer shown) notifications.
+ *
+ * Requires ACCESS_NOTIFICATIONS which is signature|system.
+ */
+ @Override
public StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count) {
// enforce() will ensure the calling uid has the correct permission
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NOTIFICATIONS,
@@ -474,27 +517,76 @@
return tmp;
}
- boolean packageCanTapNotificationsForUser(final int uid, final String pkg) {
- // Make sure the package and uid match, and that the package is allowed access
- return (AppOpsManager.MODE_ALLOWED
- == mAppOps.checkOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, pkg));
+ /**
+ * Called whenever packages change, the user switches, or ENABLED_NOTIFICATION_LISTENERS
+ * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
+ */
+ void rebindListenerServices() {
+ String flat = Settings.Secure.getString(
+ mContext.getContentResolver(),
+ Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+
+ NotificationListenerInfo[] toRemove = new NotificationListenerInfo[mListeners.size()];
+ final ArrayList<ComponentName> toAdd;
+ final int currentUser = ActivityManager.getCurrentUser();
+
+ synchronized (mNotificationList) {
+ // unbind and remove all existing listeners
+ toRemove = mListeners.toArray(toRemove);
+
+ toAdd = new ArrayList<ComponentName>();
+ final HashSet<ComponentName> newEnabled = new HashSet<ComponentName>();
+ final HashSet<String> newPackages = new HashSet<String>();
+
+ // decode the list of components
+ if (flat != null) {
+ String[] components = flat.split(ENABLED_NOTIFICATION_LISTENERS_SEPARATOR);
+ for (int i=0; i<components.length; i++) {
+ final ComponentName component
+ = ComponentName.unflattenFromString(components[i]);
+ if (component != null) {
+ newEnabled.add(component);
+ toAdd.add(component);
+ newPackages.add(component.getPackageName());
+ }
+ }
+
+ mEnabledListenersForCurrentUser = newEnabled;
+ mEnabledListenerPackageNames = newPackages;
+ }
+ }
+
+ for (NotificationListenerInfo info : toRemove) {
+ final ComponentName component = info.component;
+ final int oldUser = info.userid;
+ Slog.v(TAG, "disabling notification listener for user " + oldUser + ": " + component);
+ unregisterListenerService(component, info.userid);
+ }
+
+ final int N = toAdd.size();
+ for (int i=0; i<N; i++) {
+ final ComponentName component = toAdd.get(i);
+ Slog.v(TAG, "enabling notification listener for user " + currentUser + ": "
+ + component);
+ registerListenerService(component, currentUser);
+ }
}
+ /**
+ * Register a listener binder directly with the notification manager.
+ *
+ * Only works with system callers. Apps should extend
+ * {@link android.service.notification.NotificationListenerService}.
+ */
@Override
public void registerListener(final INotificationListener listener,
- final String pkg, final int userid) {
- // ensure system or allowed pkg
- int uid = Binder.getCallingUid();
- boolean isSystem = (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0);
- if (!(isSystem || packageCanTapNotificationsForUser(uid, pkg))) {
- throw new SecurityException("Package " + pkg
- + " may not listen for notifications");
- }
+ final ComponentName component, final int userid) {
+ checkCallerIsSystem();
synchronized (mNotificationList) {
try {
NotificationListenerInfo info
- = new NotificationListenerInfo(listener, pkg, userid, isSystem);
+ = new NotificationListenerInfo(listener, component, userid, true);
listener.asBinder().linkToDeath(info, 0);
mListeners.add(info);
} catch (RemoteException e) {
@@ -503,6 +595,90 @@
}
}
+ /**
+ * Version of registerListener that takes the name of a
+ * {@link android.service.notification.NotificationListenerService} to bind to.
+ *
+ * This is the mechanism by which third parties may subscribe to notifications.
+ */
+ private void registerListenerService(final ComponentName name, final int userid) {
+ checkCallerIsSystem();
+
+ if (DBG) Slog.v(TAG, "registerListenerService: " + name + " u=" + userid);
+
+ synchronized (mNotificationList) {
+ final String servicesBindingTag = name.toString() + "/" + userid;
+ if (mServicesBinding.contains(servicesBindingTag)) {
+ // stop registering this thing already! we're working on it
+ return;
+ }
+ mServicesBinding.add(servicesBindingTag);
+
+ final int N = mListeners.size();
+ for (int i=N-1; i>=0; i--) {
+ final NotificationListenerInfo info = mListeners.get(i);
+ if (name.equals(info.component)
+ && info.userid == userid) {
+ // cut old connections
+ if (DBG) Slog.v(TAG, " disconnecting old listener: " + info.listener);
+ mListeners.remove(i);
+ if (info.connection != null) {
+ mContext.unbindService(info.connection);
+ }
+ }
+ }
+
+ Intent intent = new Intent(NotificationListenerService.SERVICE_INTERFACE);
+ intent.setComponent(name);
+
+ intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
+ com.android.internal.R.string.notification_listener_binding_label);
+ intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+ mContext, 0, new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS), 0));
+
+ try {
+ if (DBG) Slog.v(TAG, "binding: " + intent);
+ if (!mContext.bindServiceAsUser(intent,
+ new ServiceConnection() {
+ INotificationListener mListener;
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mNotificationList) {
+ mServicesBinding.remove(servicesBindingTag);
+ try {
+ mListener = INotificationListener.Stub.asInterface(service);
+ NotificationListenerInfo info = new NotificationListenerInfo(
+ mListener, name, userid, this);
+ service.linkToDeath(info, 0);
+ mListeners.add(info);
+ } catch (RemoteException e) {
+ // already dead
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Slog.v(TAG, "notification listener connection lost: " + name);
+ }
+ },
+ Context.BIND_AUTO_CREATE,
+ new UserHandle(userid)))
+ {
+ mServicesBinding.remove(servicesBindingTag);
+ Slog.w(TAG, "Unable to bind listener service: " + intent);
+ return;
+ }
+ } catch (SecurityException ex) {
+ Slog.e(TAG, "Unable to bind listener service: " + intent, ex);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Remove a listener binder directly
+ */
@Override
public void unregisterListener(INotificationListener listener, int userid) {
// no need to check permissions; if your listener binder is in the list,
@@ -513,12 +689,39 @@
for (int i=N-1; i>=0; i--) {
final NotificationListenerInfo info = mListeners.get(i);
if (info.listener == listener && info.userid == userid) {
- mListeners.remove(listener);
+ mListeners.remove(i);
+ if (info.connection != null) {
+ mContext.unbindService(info.connection);
+ }
}
}
}
}
+ /**
+ * Remove a listener service for the given user by ComponentName
+ */
+ private void unregisterListenerService(ComponentName name, int userid) {
+ checkCallerIsSystem();
+
+ synchronized (mNotificationList) {
+ final int N = mListeners.size();
+ for (int i=N-1; i>=0; i--) {
+ final NotificationListenerInfo info = mListeners.get(i);
+ if (name.equals(info.component)
+ && info.userid == userid) {
+ mListeners.remove(i);
+ if (info.connection != null) {
+ mContext.unbindService(info.connection);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * asynchronously notify all listeners about a new notification
+ */
private void notifyPostedLocked(NotificationRecord n) {
final StatusBarNotification sbn = n.sbn;
for (final NotificationListenerInfo info : mListeners) {
@@ -530,6 +733,9 @@
}
}
+ /**
+ * asynchronously notify all listeners about a removed notification
+ */
private void notifyRemovedLocked(NotificationRecord n) {
final StatusBarNotification sbn = n.sbn;
for (final NotificationListenerInfo info : mListeners) {
@@ -541,6 +747,57 @@
}
}
+ // -- APIs to support listeners clicking/clearing notifications --
+
+ private NotificationListenerInfo checkListenerToken(INotificationListener listener) {
+ final IBinder token = listener.asBinder();
+ final int N = mListeners.size();
+ for (int i=0; i<N; i++) {
+ final NotificationListenerInfo info = mListeners.get(i);
+ if (info.listener.asBinder() == token) return info;
+ }
+ throw new SecurityException("Disallowed call from unknown listener: " + listener);
+ }
+
+ /**
+ * Allow an INotificationListener to simulate a "clear all" operation.
+ *
+ * {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onClearAllNotifications}
+ *
+ * @param token The binder for the listener, to check that the caller is allowed
+ */
+ public void clearAllNotificationsFromListener(INotificationListener token) {
+ NotificationListenerInfo info = checkListenerToken(token);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ cancelAll(info.userid);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Allow an INotificationListener to simulate clearing (dismissing) a single notification.
+ *
+ * {@see com.android.server.StatusBarManagerService.NotificationCallbacks#onNotificationClear}
+ *
+ * @param token The binder for the listener, to check that the caller is allowed
+ */
+ public void clearNotificationFromListener(INotificationListener token, String pkg, String tag, int id) {
+ NotificationListenerInfo info = checkListenerToken(token);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ cancelNotification(pkg, tag, id, 0,
+ Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+ true,
+ info.userid);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ // -- end of listener APIs --
+
public static final class NotificationRecord
{
final StatusBarNotification sbn;
@@ -759,12 +1016,23 @@
}
pkgList = new String[]{pkgName};
}
+
+ boolean anyListenersInvolved = false;
if (pkgList != null && (pkgList.length > 0)) {
for (String pkgName : pkgList) {
cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart,
UserHandle.USER_ALL);
+ if (mEnabledListenerPackageNames.contains(pkgName)) {
+ anyListenersInvolved = true;
+ }
}
}
+
+ if (anyListenersInvolved) {
+ // make sure we're still bound to any of our
+ // listeners who may have just upgraded
+ rebindListenerServices();
+ }
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
// Keep track of screen on/off state, but do not turn off the notification light
// until user passes through the lock screen or views the notification.
@@ -795,7 +1063,7 @@
= Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
private final Uri ENABLED_NOTIFICATION_LISTENERS_URI
- = Settings.System.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+ = Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
SettingsObserver(Handler handler) {
super(handler);
@@ -804,9 +1072,9 @@
void observe() {
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
- false, this);
+ false, this, UserHandle.USER_ALL);
resolver.registerContentObserver(ENABLED_NOTIFICATION_LISTENERS_URI,
- false, this);
+ false, this, UserHandle.USER_ALL);
update(null);
}
@@ -825,19 +1093,7 @@
}
}
if (uri == null || ENABLED_NOTIFICATION_LISTENERS_URI.equals(uri)) {
- String pkglist = Settings.Secure.getString(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
- mEnabledListenersForCurrentUser.clear();
- if (pkglist != null) {
- String[] pkgs = pkglist.split(";");
- for (int i=0; i<pkgs.length; i++) {
- final String pkg = pkgs[i];
- if (pkg != null && ! "".equals(pkg)) {
- mEnabledListenersForCurrentUser.add(pkgs[i]);
- }
- }
- }
+ rebindListenerServices();
}
}
}
@@ -956,6 +1212,9 @@
// no beeping until we're basically done booting
mSystemReady = true;
+
+ // make sure our listener services are properly bound
+ rebindListenerServices();
}
// Toasts
@@ -1781,16 +2040,17 @@
pw.println("Current Notification Manager state:");
- pw.print(" Enabled listeners: [");
- for (String pkg : mEnabledListenersForCurrentUser) {
- pw.print(" " + pkg);
+ pw.println(" Listeners (" + mEnabledListenersForCurrentUser.size()
+ + ") enabled for current user:");
+ for (ComponentName cmpt : mEnabledListenersForCurrentUser) {
+ pw.println(" " + cmpt);
}
- pw.println(" ]");
- pw.println(" Live listeners:");
+ pw.println(" Live listeners (" + mListeners.size() + "):");
for (NotificationListenerInfo info : mListeners) {
- pw.println(" " + info.pkg + " (user " + info.userid + "): " + info.listener
- + (info.isSystem?" SYSTEM":""));
+ pw.println(" " + info.component
+ + " (user " + info.userid + "): " + info.listener
+ + (info.isSystem?" SYSTEM":""));
}
int N;
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 1fe98af..c21d8c6 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.app.StatusBarManager;
+import android.service.notification.StatusBarNotification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -33,7 +34,6 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
-import com.android.internal.statusbar.StatusBarNotification;
import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 8ff1c7d..fccaab5 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -376,37 +376,37 @@
// icon, but this used to be able to slip through, so for
// those dirty apps give it the app's icon.
foregroundNoti.icon = appInfo.icon;
- if (foregroundNoti.contentView == null) {
- // In this case the app may not have specified a
- // content view... so we'll give them something to show.
- CharSequence appName = appInfo.loadLabel(
- ams.mContext.getPackageManager());
- if (appName == null) {
- appName = appInfo.packageName;
- }
- Context ctx = null;
- try {
- ctx = ams.mContext.createPackageContext(
- appInfo.packageName, 0);
- Intent runningIntent = new Intent(
- Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
- runningIntent.setData(Uri.fromParts("package",
- appInfo.packageName, null));
- PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0,
- runningIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- foregroundNoti.setLatestEventInfo(ctx,
- ams.mContext.getString(
- com.android.internal.R.string
- .app_running_notification_title,
- appName),
- ams.mContext.getString(
- com.android.internal.R.string
- .app_running_notification_text,
- appName),
- pi);
- } catch (PackageManager.NameNotFoundException e) {
- foregroundNoti.icon = 0;
- }
+
+ // Do not allow apps to present a sneaky invisible content view either.
+ foregroundNoti.contentView = null;
+ foregroundNoti.bigContentView = null;
+ CharSequence appName = appInfo.loadLabel(
+ ams.mContext.getPackageManager());
+ if (appName == null) {
+ appName = appInfo.packageName;
+ }
+ Context ctx = null;
+ try {
+ ctx = ams.mContext.createPackageContext(
+ appInfo.packageName, 0);
+ Intent runningIntent = new Intent(
+ Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ runningIntent.setData(Uri.fromParts("package",
+ appInfo.packageName, null));
+ PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0,
+ runningIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ foregroundNoti.setLatestEventInfo(ctx,
+ ams.mContext.getString(
+ com.android.internal.R.string
+ .app_running_notification_title,
+ appName),
+ ams.mContext.getString(
+ com.android.internal.R.string
+ .app_running_notification_text,
+ appName),
+ pi);
+ } catch (PackageManager.NameNotFoundException e) {
+ foregroundNoti.icon = 0;
}
}
if (foregroundNoti.icon == 0) {
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index d603cfa..c94f7c1 100644
--- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -226,8 +226,6 @@
FileOutputStream out = null;
File tmp = null;
try {
- // create the temporary file
- tmp = File.createTempFile("journal", "", dir);
// create the parents for the destination file
File parent = file.getParentFile();
parent.mkdirs();
@@ -235,6 +233,8 @@
if (!parent.exists()) {
throw new IOException("Failed to create directory " + parent.getCanonicalPath());
}
+ // create the temporary file
+ tmp = File.createTempFile("journal", "", dir);
// mark tmp -rw-r--r--
tmp.setReadable(true, false);
// write to it
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 3ed9cef..674955c 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -274,6 +274,33 @@
}
/**
+ * Make a SignalStrength object from the given parcel as passed up by
+ * the ril which does not have isGsm. isGsm will be changed by ServiceStateTracker
+ * so the default is a don't care.
+ *
+ * @hide
+ */
+ public static SignalStrength makeSignalStrengthFromRilParcel(Parcel in) {
+ if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
+
+ SignalStrength ss = new SignalStrength();
+ ss.mGsmSignalStrength = in.readInt();
+ ss.mGsmBitErrorRate = in.readInt();
+ ss.mCdmaDbm = in.readInt();
+ ss.mCdmaEcio = in.readInt();
+ ss.mEvdoDbm = in.readInt();
+ ss.mEvdoEcio = in.readInt();
+ ss.mEvdoSnr = in.readInt();
+ ss.mLteSignalStrength = in.readInt();
+ ss.mLteRsrp = in.readInt();
+ ss.mLteRsrq = in.readInt();
+ ss.mLteRssnr = in.readInt();
+ ss.mLteCqi = in.readInt();
+
+ return ss;
+ }
+
+ /**
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(Parcel out, int flags) {
diff --git a/tests/RenderScriptTests/FBOTest/Android.mk b/tests/RenderScriptTests/FBOTest/Android.mk
index 434d592..7a578d9 100644
--- a/tests/RenderScriptTests/FBOTest/Android.mk
+++ b/tests/RenderScriptTests/FBOTest/Android.mk
@@ -23,4 +23,6 @@
LOCAL_PACKAGE_NAME := FBOTest
+LOCAL_SDK_VERSION := 17
+
include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/Fountain/Android.mk b/tests/RenderScriptTests/Fountain/Android.mk
index 4a6560b..0517aef 100644
--- a/tests/RenderScriptTests/Fountain/Android.mk
+++ b/tests/RenderScriptTests/Fountain/Android.mk
@@ -21,8 +21,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
-# TODO: build fails with this set
-# LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 17
LOCAL_PACKAGE_NAME := RsFountain
diff --git a/tests/RenderScriptTests/HelloWorld/Android.mk b/tests/RenderScriptTests/HelloWorld/Android.mk
index 54824f4..c1c08ec 100644
--- a/tests/RenderScriptTests/HelloWorld/Android.mk
+++ b/tests/RenderScriptTests/HelloWorld/Android.mk
@@ -23,6 +23,6 @@
LOCAL_PACKAGE_NAME := RsHelloWorld
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 17
include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/MiscSamples/Android.mk b/tests/RenderScriptTests/MiscSamples/Android.mk
index bdff46a..ee3567b 100644
--- a/tests/RenderScriptTests/MiscSamples/Android.mk
+++ b/tests/RenderScriptTests/MiscSamples/Android.mk
@@ -23,6 +23,6 @@
LOCAL_PACKAGE_NAME := RsMiscSamples
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := 17
include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/ModelViewer/Android.mk b/tests/RenderScriptTests/ModelViewer/Android.mk
index 18ceac5..86724cf 100644
--- a/tests/RenderScriptTests/ModelViewer/Android.mk
+++ b/tests/RenderScriptTests/ModelViewer/Android.mk
@@ -22,6 +22,8 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+LOCAL_SDK_VERSION := 17
+
LOCAL_PACKAGE_NAME := ModelViewer
include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/PerfTest/Android.mk b/tests/RenderScriptTests/PerfTest/Android.mk
index 0d1e7d2..e9ee771 100644
--- a/tests/RenderScriptTests/PerfTest/Android.mk
+++ b/tests/RenderScriptTests/PerfTest/Android.mk
@@ -24,6 +24,8 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+LOCAL_SDK_VERSION := 17
+
LOCAL_PACKAGE_NAME := PerfTest
include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/SceneGraph/Android.mk b/tests/RenderScriptTests/SceneGraph/Android.mk
index 163a95d..6047305 100644
--- a/tests/RenderScriptTests/SceneGraph/Android.mk
+++ b/tests/RenderScriptTests/SceneGraph/Android.mk
@@ -21,6 +21,8 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+LOCAL_SDK_VERSION := 17
+
LOCAL_PACKAGE_NAME := SceneGraphTest
include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/ShadersTest/Android.mk b/tests/RenderScriptTests/ShadersTest/Android.mk
index 0912591..fb6356e 100644
--- a/tests/RenderScriptTests/ShadersTest/Android.mk
+++ b/tests/RenderScriptTests/ShadersTest/Android.mk
@@ -21,6 +21,8 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+LOCAL_SDK_VERSION := 17
+
LOCAL_PACKAGE_NAME := ShadersTest
include $(BUILD_PACKAGE)
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
index 5d0b155..c7c8aa2 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
@@ -49,6 +49,8 @@
{
private final static String TAG = "NotificationTestList";
+ private final static String NOTIFY_TAG = "foo";
+
NotificationManager mNM;
Handler mHandler;
int mStartDelay;
@@ -196,7 +198,7 @@
final Notification n = buildNotification(id);
mHandler.postDelayed(new Runnable() {
public void run() {
- mNM.notify(id, n);
+ mNM.notify(NOTIFY_TAG, id, n);
}
}, mStartDelay);
}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 4345098..ba160b1 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -33,13 +33,10 @@
import android.net.Uri;
import android.os.SystemClock;
import android.widget.RemoteViews;
-import android.widget.TextView;
-import android.widget.ProgressBar;
import android.os.PowerManager;
// private NM API
import android.app.INotificationManager;
-import com.android.internal.statusbar.StatusBarNotification;
public class NotificationTestList extends TestActivity
{