Merge "CTS tests for Contactables api" into jb-mr2-dev
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineMesh.cpp b/suite/pts/deviceTests/opengl/jni/graphics/BasicMeshNode.cpp
similarity index 83%
rename from suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineMesh.cpp
rename to suite/pts/deviceTests/opengl/jni/graphics/BasicMeshNode.cpp
index bf1b9d2..273517a 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineMesh.cpp
+++ b/suite/pts/deviceTests/opengl/jni/graphics/BasicMeshNode.cpp
@@ -12,20 +12,21 @@
* the License.
*/
-#include "FullPipelineMesh.h"
+#include "BasicMeshNode.h"
-#include <graphics/BasicProgram.h>
+#include "BasicProgram.h"
-FullPipelineMesh::FullPipelineMesh(const Mesh* mesh) :
- MeshNode(mesh) {
+BasicMeshNode::BasicMeshNode(const Mesh* mesh, const GLuint textureId) :
+ MeshNode(mesh),
+ mTextureId(textureId) {
}
-void FullPipelineMesh::before(Program& program, Matrix& model, Matrix& view, Matrix& projection) {
+void BasicMeshNode::before(Program& program, Matrix& model, Matrix& view, Matrix& projection) {
BasicProgram& prog = (BasicProgram&) program;
glActiveTexture(GL_TEXTURE0);
// Bind the texture to this unit.
- glBindTexture(GL_TEXTURE_2D, mMesh->mTextureId);
+ glBindTexture(GL_TEXTURE_2D, mTextureId);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture
// unit 0.
glUniform1i(prog.mTextureUniformHandle, 0);
@@ -58,5 +59,5 @@
glDrawArrays(GL_TRIANGLES, 0, mMesh->mNumVertices);
}
-void FullPipelineMesh::after(Program& program, Matrix& model, Matrix& view, Matrix& projection) {
+void BasicMeshNode::after(Program& program, Matrix& model, Matrix& view, Matrix& projection) {
}
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineMesh.h b/suite/pts/deviceTests/opengl/jni/graphics/BasicMeshNode.h
similarity index 73%
rename from suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineMesh.h
rename to suite/pts/deviceTests/opengl/jni/graphics/BasicMeshNode.h
index 3fcb8ae..97cd24b 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineMesh.h
+++ b/suite/pts/deviceTests/opengl/jni/graphics/BasicMeshNode.h
@@ -12,23 +12,24 @@
* the License.
*/
-#ifndef FULLPIPELINEMESH_H
-#define FULLPIPELINEMESH_H
+#ifndef BASICMESHNODE_H
+#define BASICMESHNODE_H
-#include <graphics/Matrix.h>
-#include <graphics/Mesh.h>
-#include <graphics/MeshNode.h>
-#include <graphics/Program.h>
+#include "Matrix.h"
+#include "Mesh.h"
+#include "MeshNode.h"
+#include "Program.h"
-class FullPipelineMesh: public MeshNode {
+class BasicMeshNode: public MeshNode {
public:
- FullPipelineMesh(const Mesh* mesh);
- virtual ~FullPipelineMesh() {};
+ BasicMeshNode(const Mesh* mesh, const GLuint textureId);
+ virtual ~BasicMeshNode() {};
protected:
virtual void before(Program& program, Matrix& model, Matrix& view,
Matrix& projection);
virtual void after(Program& program, Matrix& model, Matrix& view,
Matrix& projection);
+ const GLuint mTextureId;
};
#endif
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
index ed6f84b6..2484153 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
+++ b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
@@ -101,7 +101,7 @@
return x + 1;
}
-GLuint GLUtils::genRandTex(int texWidth, int texHeight) {
+GLuint GLUtils::genTexture(int texWidth, int texHeight, int fill) {
GLuint textureId = 0;
int w = roundUpToSmallestPowerOf2(texWidth);
int h = roundUpToSmallestPowerOf2(texHeight);
@@ -110,8 +110,11 @@
uint32_t* d = m;
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
- *d = 0xff000000 | ((y & 0xff) << 16) | ((x & 0xff) << 8)
- | ((x + y) & 0xff);
+ if (fill == RANDOM_FILL) {
+ *d = 0xff000000 | ((y & 0xff) << 16) | ((x & 0xff) << 8) | ((x + y) & 0xff);
+ } else {
+ *d = 0xff000000 | fill;
+ }
d++;
}
}
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.h b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.h
index 3d3bafd..16060ed 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.h
+++ b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.h
@@ -26,8 +26,11 @@
static double currentTimeMillis();
// Rounds a number up to the smallest power of 2 that is greater than the original number.
static int roundUpToSmallestPowerOf2(int x);
- // Generates a random texture of the given dimensions.
- static GLuint genRandTex(int texWidth, int texHeight);
+ static const int RANDOM_FILL = -1;
+ // Generates a texture of the given dimensions. The texture can either be filled with the
+ // specified fill color, else if RANDOM_FILL is passed in the texture will be filled with
+ // random values.
+ static GLuint genTexture(int texWidth, int texHeight, int fill);
static bool createFBO(GLuint& fboId, GLuint& rboId, GLuint& cboId, int width, int height);
};
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/Mesh.cpp b/suite/pts/deviceTests/opengl/jni/graphics/Mesh.cpp
index b92551c..858ec6b 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/Mesh.cpp
+++ b/suite/pts/deviceTests/opengl/jni/graphics/Mesh.cpp
@@ -14,11 +14,10 @@
#include "Mesh.h"
Mesh::Mesh(const float* vertices, const float* normals, const float* texCoords,
- const int numVertices, const GLuint textureId)
+ const int numVertices)
: mVertices(vertices),
mNormals(normals),
mTexCoords(texCoords),
- mNumVertices(numVertices),
- mTextureId(textureId) {
+ mNumVertices(numVertices) {
}
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/Mesh.h b/suite/pts/deviceTests/opengl/jni/graphics/Mesh.h
index 5f5ac7d..9ff4103 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/Mesh.h
+++ b/suite/pts/deviceTests/opengl/jni/graphics/Mesh.h
@@ -21,13 +21,12 @@
class Mesh {
public:
Mesh(const float* vertices, const float* normals, const float* texCoords,
- const int numVertices, const GLuint textureId);
+ const int numVertices);
virtual ~Mesh() {};
const float* mVertices;
const float* mNormals;
const float* mTexCoords;
const int mNumVertices;
- const GLuint mTextureId;
};
#endif
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/Renderer.cpp b/suite/pts/deviceTests/opengl/jni/graphics/Renderer.cpp
index ece115e..e9d083d 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/Renderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/graphics/Renderer.cpp
@@ -74,20 +74,20 @@
return false;
}
- if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &width)
+ if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth)
|| EGL_SUCCESS != eglGetError()) {
return false;
}
- if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &height)
+ if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight)
|| EGL_SUCCESS != eglGetError()) {
return false;
}
- glViewport(0, 0, width, height);
+ glViewport(0, 0, mWidth, mHeight);
if (mOffscreen) {
- mFboWidth = GLUtils::roundUpToSmallestPowerOf2(width);
- mFboHeight = GLUtils::roundUpToSmallestPowerOf2(height);
+ mFboWidth = GLUtils::roundUpToSmallestPowerOf2(mWidth);
+ mFboHeight = GLUtils::roundUpToSmallestPowerOf2(mHeight);
if (!GLUtils::createFBO(mFboId, mRboId, mCboId, mFboWidth, mFboHeight)) {
return false;
}
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/Renderer.h b/suite/pts/deviceTests/opengl/jni/graphics/Renderer.h
index cbe9419..8da504d 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/Renderer.h
+++ b/suite/pts/deviceTests/opengl/jni/graphics/Renderer.h
@@ -40,8 +40,8 @@
GLuint mCboId;// Color buffer id
GLushort* mBuffer;// Used for FBO read back
GLuint mProgramId;
- EGLint width;
- EGLint height;
+ EGLint mWidth;
+ EGLint mHeight;
bool mOffscreen;
int mWorkload;
};
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/Vector2D.cpp b/suite/pts/deviceTests/opengl/jni/graphics/Vector2D.cpp
new file mode 100644
index 0000000..d4a8c18
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/graphics/Vector2D.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+#include "Vector2D.h"
+
+#include <math.h>
+
+Vector2D::Vector2D() :
+ mX(0), mY(0) {
+}
+
+Vector2D::Vector2D(float x, float y) :
+ mX(x), mY(y) {
+}
+
+Vector2D Vector2D::copy() {
+ Vector2D v(mX, mY);
+ return v;
+}
+
+void Vector2D::add(const Vector2D& v) {
+ mX += v.mX;
+ mY += v.mY;
+}
+
+void Vector2D::sub(const Vector2D& v) {
+ mX -= v.mX;
+ mY -= v.mY;
+}
+
+void Vector2D::scale(float s) {
+ mX *= s;
+ mY *= s;
+}
+
+float Vector2D::distance(const Vector2D& v) {
+ float dx = mX - v.mX;
+ float dy = mY - v.mY;
+ return (float) sqrt(dx * dx + dy * dy);
+}
+
+void Vector2D::normalize() {
+ float m = magnitude();
+ if (m > 0) {
+ scale(1 / m);
+ }
+}
+
+void Vector2D::limit(float max) {
+ if (magnitude() > max) {
+ normalize();
+ scale(max);
+ }
+}
+
+float Vector2D::magnitude() {
+ return (float) sqrt(mX * mX + mY * mY);
+}
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/Vector2D.h b/suite/pts/deviceTests/opengl/jni/graphics/Vector2D.h
new file mode 100644
index 0000000..5110975
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/graphics/Vector2D.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+#ifndef VECTOR2D_H
+#define VECTOR2D_H
+
+class Vector2D {
+public:
+ Vector2D();
+ Vector2D(float x, float y);
+ Vector2D copy();
+ void normalize();
+ void add(const Vector2D& v);
+ void sub(const Vector2D& v);
+ void scale(float s);
+ void limit(float max);
+ void limit(float maxX, float maxY);
+ float magnitude();
+ float distance(const Vector2D& v);
+ float mX;
+ float mY;
+};
+#endif
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
index 44e8909..8865c99 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
@@ -25,11 +25,14 @@
#include <Trace.h>
-static const EGLint contextAttribs[] =
- { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+static const EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE };
static const int NUM_WORKER_CONTEXTS = 7;
+static const int CS_TEXTURE_SIZE = 64;
+
static const int CS_NUM_VERTICES = 6;
static const float CS_VERTICES[CS_NUM_VERTICES * 3] = {
@@ -78,7 +81,7 @@
}
// Setup texture.
- mTextureId = GLUtils::genRandTex(64, 64);
+ mTextureId = GLUtils::genTexture(CS_TEXTURE_SIZE, CS_TEXTURE_SIZE, GLUtils::RANDOM_FILL);
if (mTextureId == 0) {
return false;
}
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
index da65420..01b143b 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
@@ -15,11 +15,11 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include "FullPipelineMesh.h"
#include "FullPipelineRenderer.h"
-#include <graphics/TransformationNode.h>
+#include <graphics/BasicMeshNode.h>
#include <graphics/GLUtils.h>
+#include <graphics/TransformationNode.h>
#include <Trace.h>
@@ -104,8 +104,9 @@
}
mProgramId = GLUtils::createProgram(&FP_VERTEX, &FP_FRAGMENT);
- if (mProgramId == 0)
+ if (mProgramId == 0) {
return false;
+ }
mProgram = new BasicProgram(mProgramId);
mModelMatrix = new Matrix();
@@ -130,7 +131,7 @@
// Create a new perspective projection matrix. The height will stay the same
// while the width will vary as per aspect ratio.
- float ratio = (float) width / height;
+ float ratio = (float) mWidth / mHeight;
float left = -ratio;
float right = ratio;
float bottom = -1.0f;
@@ -141,7 +142,7 @@
mProjectionMatrix = Matrix::newFrustum(left, right, bottom, top, near, far);
// Setup texture.
- mTextureId = GLUtils::genRandTex(width, height);
+ mTextureId = GLUtils::genTexture(mWidth, mHeight, GLUtils::RANDOM_FILL);
if (mTextureId == 0) {
return false;
}
@@ -150,7 +151,7 @@
float middle = count / 2.0f;
float scale = 2.0f / count;
- mMesh = new Mesh(FP_VERTICES, FP_NORMALS, FP_TEX_COORDS, FP_NUM_VERTICES, mTextureId);
+ mMesh = new Mesh(FP_VERTICES, FP_NORMALS, FP_TEX_COORDS, FP_NUM_VERTICES);
mSceneGraph = new ProgramNode();
for (int i = 0; i < count; i++) {
@@ -159,7 +160,7 @@
transformMatrix->translate(i - middle, j - middle, 0.0f);
TransformationNode* transformNode = new TransformationNode(transformMatrix);
mSceneGraph->addChild(transformNode);
- FullPipelineMesh* meshNode = new FullPipelineMesh(mMesh);
+ BasicMeshNode* meshNode = new BasicMeshNode(mMesh, mTextureId);
transformNode->addChild(meshNode);
}
}
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
index 321235d..3fdafca 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
@@ -62,15 +62,16 @@
// Create program.
mProgramId = GLUtils::createProgram(&PO_VERTEX, &PO_FRAGMENT);
- if (mProgramId == 0)
+ if (mProgramId == 0) {
return false;
+ }
// Bind attributes.
mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
// Setup texture.
- mTextureId = GLUtils::genRandTex(width, height);
+ mTextureId = GLUtils::genTexture(mWidth, mHeight, GLUtils::RANDOM_FILL);
if (mTextureId == 0) {
return false;
}
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
index cff8599..85e6af3 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
@@ -112,8 +112,9 @@
// Create program.
mProgramId = GLUtils::createProgram(&SP_VERTEX, const_cast<const char**>(&spFragment));
delete[] spFragment;
- if (mProgramId == 0)
+ if (mProgramId == 0) {
return false;
+ }
// Bind attributes.
mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
mSeedUniformHandle = glGetUniformLocation(mProgramId, "u_Seed");
diff --git a/suite/pts/deviceTests/opengl/jni/reference/GLReference.cpp b/suite/pts/deviceTests/opengl/jni/reference/GLReference.cpp
index 53a262e..333e0da 100644
--- a/suite/pts/deviceTests/opengl/jni/reference/GLReference.cpp
+++ b/suite/pts/deviceTests/opengl/jni/reference/GLReference.cpp
@@ -13,10 +13,46 @@
*/
#include <jni.h>
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+
+#include <graphics/GLUtils.h>
+#include <graphics/Renderer.h>
+
+#include "ReferenceRenderer.h"
+
extern "C" JNIEXPORT jboolean JNICALL
Java_com_android_pts_opengl_reference_GLGameActivity_startBenchmark(
JNIEnv* env, jclass clazz, jobject surface, jint numFrames,
jdoubleArray setUpTimes, jdoubleArray updateTimes, jdoubleArray renderTimes) {
- // TODO
- return true;
+
+ if (numFrames > (ReferenceRenderer::FRAMES_PER_SCENE * ReferenceRenderer::NUM_SCENES)) {
+ return false;
+ }
+
+ ReferenceRenderer* gRenderer = new ReferenceRenderer(ANativeWindow_fromSurface(env, surface));
+
+ bool success = gRenderer->setUp();
+ env->SetDoubleArrayRegion(
+ setUpTimes, 0, ReferenceRenderer::NUM_SETUP_TIMES, gRenderer->mSetUpTimes);
+
+ double updates[numFrames];
+ double renders[numFrames];
+ for (int i = 0; i < numFrames && success; i++) {
+ double t0 = GLUtils::currentTimeMillis();
+ success = gRenderer->update(i);
+ double t1 = GLUtils::currentTimeMillis();
+ success = success && gRenderer->draw();
+ double t2 = GLUtils::currentTimeMillis();
+ updates[i] = t1 - t0;
+ renders[i] = t2 - t1;
+ }
+
+ env->SetDoubleArrayRegion(updateTimes, 0, numFrames, updates);
+ env->SetDoubleArrayRegion(renderTimes, 0, numFrames, renders);
+
+ success = gRenderer->tearDown() && success;
+ delete gRenderer;
+ gRenderer = NULL;
+ return success;
}
diff --git a/suite/pts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp b/suite/pts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
new file mode 100644
index 0000000..a168246
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+#include "ReferenceRenderer.h"
+
+#include "scene/flocking/FlockingScene.h"
+
+#include <graphics/GLUtils.h>
+#include <graphics/ProgramNode.h>
+
+#include <Trace.h>
+
+ReferenceRenderer::ReferenceRenderer(ANativeWindow* window) :
+ Renderer(window, false, 0) {
+}
+
+bool ReferenceRenderer::setUp() {
+ SCOPED_TRACE();
+ // Reset the times.
+ for (int i = 0; i < NUM_SETUP_TIMES; i++) {
+ mSetUpTimes[i] = 0;
+ }
+ // Set up OpenGLES.
+ double start = GLUtils::currentTimeMillis();
+ if (!Renderer::setUp()) {
+ return false;
+ }
+ mSetUpTimes[0] = GLUtils::currentTimeMillis() - start;
+
+ // Create the scenes.
+ mScenes[0] = new FlockingScene(mWidth, mHeight);
+ // TODO add more scenes to do a comprehensive test.
+
+ // Set up the scenes.
+ double times[NUM_SETUP_TIMES];
+ for (int i = 0; i < NUM_SCENES; i++) {
+ times[0] = GLUtils::currentTimeMillis();
+ mScenes[i]->setUpContext();
+ times[1] = GLUtils::currentTimeMillis();
+ mScenes[i]->setUpTextures();
+ times[2] = GLUtils::currentTimeMillis();
+ mScenes[i]->setUpMeshes();
+ times[3] = GLUtils::currentTimeMillis();
+
+ for (int i = 1; i < NUM_SETUP_TIMES; i++) {
+ // Add on the set up times.
+ mSetUpTimes[i] += times[i] - times[i - 1];
+ }
+ }
+ return true;
+}
+
+bool ReferenceRenderer::tearDown() {
+ SCOPED_TRACE();
+ for (int i = 0; i < NUM_SCENES; i++) {
+ mScenes[i]->tearDown();
+ delete mScenes[i];
+ }
+ mCurrentScene = NULL;
+ if (!Renderer::tearDown()) {
+ return false;
+ }
+ return true;
+}
+
+bool ReferenceRenderer::update(int frame) {
+ SCOPED_TRACE();
+ int sceneId = frame / ReferenceRenderer::FRAMES_PER_SCENE;
+ int localFrame = frame % ReferenceRenderer::FRAMES_PER_SCENE;
+ mCurrentScene = mScenes[sceneId];
+ mCurrentScene->update(localFrame);
+ return true;
+}
+
+bool ReferenceRenderer::draw() {
+ SCOPED_TRACE();
+ if (mOffscreen) {
+ glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
+ }
+ // Set the background clear color to black.
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ // Use culling to remove back faces.
+ glEnable(GL_CULL_FACE);
+ // Use depth testing.
+ glEnable(GL_DEPTH_TEST);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ mCurrentScene->draw();
+
+ return Renderer::draw();
+}
diff --git a/suite/pts/deviceTests/opengl/jni/reference/ReferenceRenderer.h b/suite/pts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
new file mode 100644
index 0000000..fa77ec1
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+#ifndef REFERENCERENDERER_H
+#define REFERENCERENDERER_H
+
+#include "scene/Scene.h"
+
+#include <graphics/Mesh.h>
+#include <graphics/Renderer.h>
+
+class ReferenceRenderer: public Renderer {
+public:
+ ReferenceRenderer(ANativeWindow* window);
+ virtual ~ReferenceRenderer() {};
+ bool setUp();
+ bool tearDown();
+ bool update(int frame);
+ bool draw();
+ double mSetUpTimes[4];
+ static const int FRAMES_PER_SCENE = 500;
+ static const int NUM_SCENES = 1;
+ static const int NUM_SETUP_TIMES = 4;
+private:
+ Scene* mScenes[NUM_SCENES];
+ Scene* mCurrentScene;
+
+};
+
+#endif
diff --git a/suite/pts/deviceTests/opengl/jni/reference/scene/Scene.cpp b/suite/pts/deviceTests/opengl/jni/reference/scene/Scene.cpp
new file mode 100644
index 0000000..7ea889b
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/scene/Scene.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+#include "Scene.h"
+
+#include <graphics/GLUtils.h>
+#include <graphics/ProgramNode.h>
+
+#include <Trace.h>
+
+Scene::Scene(int width, int height) :
+ mWidth(width), mHeight(height), mSceneGraph(NULL) {
+}
+
+bool Scene::setUpContext() {
+ SCOPED_TRACE();
+ mProgram = setUpProgram();
+ if (mProgram == NULL) {
+ return false;
+ }
+ mModelMatrix = setUpModelMatrix();
+ if (mModelMatrix == NULL) {
+ return false;
+ }
+ mViewMatrix = setUpViewMatrix();
+ if (mViewMatrix == NULL) {
+ return false;
+ }
+ mProjectionMatrix = setUpProjectionMatrix();
+ if (mProjectionMatrix == NULL) {
+ return false;
+ }
+ return true;
+}
+
+bool Scene::tearDown() {
+ SCOPED_TRACE();
+ for (size_t i = 0; i < mTextureIds.size(); i++) {
+ glDeleteTextures(1, &(mTextureIds[i]));
+ }
+ for (size_t i = 0; i < mMeshes.size(); i++) {
+ delete mMeshes[i];
+ }
+ delete mProgram;
+ mProgram = NULL;
+ delete mSceneGraph;
+ mSceneGraph = NULL;
+ delete mModelMatrix;
+ mModelMatrix = NULL;
+ delete mViewMatrix;
+ mViewMatrix = NULL;
+ delete mProjectionMatrix;
+ mProjectionMatrix = NULL;
+ return true;
+}
+
+bool Scene::update(int frame) {
+ SCOPED_TRACE();
+ delete mSceneGraph; // Delete the old scene graph.
+ mSceneGraph = updateSceneGraph();
+ if (mSceneGraph == NULL) {
+ return false;
+ }
+ return true;
+}
+
+bool Scene::draw() {
+ SCOPED_TRACE();
+ mSceneGraph->draw(*mProgram, *mModelMatrix, *mViewMatrix, *mProjectionMatrix);
+ return true;
+}
diff --git a/suite/pts/deviceTests/opengl/jni/reference/scene/Scene.h b/suite/pts/deviceTests/opengl/jni/reference/scene/Scene.h
new file mode 100644
index 0000000..1adb850
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/scene/Scene.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+#ifndef SCENE_H
+#define SCENE_H
+
+#include <graphics/Matrix.h>
+#include <graphics/Mesh.h>
+#include <graphics/Program.h>
+#include <graphics/SceneGraphNode.h>
+
+#include <utils/Vector.h>
+
+class Scene {
+public:
+ Scene(int width, int height);
+ virtual ~Scene() {};
+ virtual bool setUpContext();
+ virtual bool setUpTextures() = 0;
+ virtual bool setUpMeshes() = 0;
+ virtual bool tearDown();
+ virtual bool update(int frame);
+ virtual bool draw();
+protected:
+ virtual Program* setUpProgram() = 0;
+ virtual Matrix* setUpModelMatrix() = 0;
+ virtual Matrix* setUpViewMatrix() = 0;
+ virtual Matrix* setUpProjectionMatrix() = 0;
+ virtual SceneGraphNode* updateSceneGraph() = 0;
+ int mWidth;
+ int mHeight;
+ android::Vector<Mesh*> mMeshes;
+ android::Vector<GLuint> mTextureIds;
+private:
+ Program* mProgram;
+ SceneGraphNode* mSceneGraph;
+ Matrix* mModelMatrix;
+ Matrix* mViewMatrix;
+ Matrix* mProjectionMatrix;
+};
+#endif
diff --git a/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/Boid.cpp b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/Boid.cpp
new file mode 100644
index 0000000..74eef81
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/Boid.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+#include "Boid.h"
+
+Boid::Boid(float x, float y) :
+ mPosition(x, y) {
+}
+
+void Boid::flock(const Boid* boids[], int numBoids, int index, float limitX, float limitY) {
+ // Reset the acceleration.
+ mAcceleration.mX = 0;
+ mAcceleration.mY = 0;
+ Vector2D separation;
+ int separationCount = 0;
+ Vector2D alignment;
+ int alignmentCount = 0;
+ Vector2D cohesion;
+ int cohesionCount = 0;
+ for (int i = 0; i < numBoids; i++) {
+ if (i != index) {
+ const Boid* b = boids[i];
+ float dist = mPosition.distance(b->mPosition);
+ if (dist != 0) {
+ // Separation.
+ if (dist < DESIRED_BOID_DIST) {
+ Vector2D tmp = mPosition.copy();
+ tmp.sub(b->mPosition);
+ tmp.normalize();
+ tmp.scale(1.0f / dist);
+ separation.add(tmp);
+ separationCount++;
+ }
+ if (dist < NEIGHBOUR_RADIUS) {
+ // Alignment.
+ alignment.add(b->mVelocity);
+ alignmentCount++;
+ // Cohesion.
+ cohesion.add(b->mPosition);
+ cohesionCount++;
+ }
+ }
+ }
+ }
+
+ if (separationCount > 0) {
+ separation.scale(1.0f / separationCount);
+ separation.scale(SEPARATION_WEIGHT);
+ mAcceleration.add(separation);
+ }
+ if (alignmentCount > 0) {
+ alignment.scale(1.0f / alignmentCount);
+ alignment.limit(MAX_FORCE);
+ alignment.scale(ALIGNMENT_WEIGHT);
+ mAcceleration.add(alignment);
+ }
+ if (cohesionCount > 0) {
+ cohesion.scale(1.0f / cohesionCount);
+ cohesion.scale(COHESION_WEIGHT);
+ Vector2D desired = cohesion.copy();
+ desired.sub(mPosition);
+ float d = desired.magnitude();
+ if (d > 0) {
+ desired.normalize();
+ desired.scale(MAX_SPEED * ((d < 100.0f) ? d / 100.0f : 1));
+ desired.sub(mVelocity);
+ desired.limit(MAX_FORCE);
+ mAcceleration.add(desired);
+ }
+ }
+
+ mVelocity.add(mAcceleration);
+ mVelocity.limit(MAX_SPEED);
+ mPosition.add(mVelocity);
+ // Wrap around.
+ if (mPosition.mX < -limitX) {
+ mPosition.mX = limitX;
+ } else if (mPosition.mX > limitX) {
+ mPosition.mX = -limitX;
+ }
+ if (mPosition.mY < -limitY) {
+ mPosition.mY = limitY;
+ } else if (mPosition.mY > limitY) {
+ mPosition.mY = -limitY;
+ }
+}
diff --git a/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
new file mode 100644
index 0000000..955b891
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+// An implementation of Craig Reynold's Boid Simulation.
+#ifndef BOID_H
+#define BOID_H
+
+#include <graphics/Vector2D.h>
+
+class Boid {
+public:
+ Boid(float x, float y);
+ void resetAcceleration();
+ void flock(const Boid* boids[], int numBoids, int index, float limitX, float limitY);
+ static const float MAX_SPEED = 2.0f;
+ static const float MAX_FORCE = 0.05f;
+ static const float NEIGHBOUR_RADIUS = 70.0f;//50
+ static const float DESIRED_BOID_DIST = 30.0f;//25
+ static const float SEPARATION_WEIGHT = 2.0f;
+ static const float ALIGNMENT_WEIGHT = 1.0f;
+ static const float COHESION_WEIGHT = 1.0f;
+ Vector2D mPosition;
+ Vector2D mVelocity;
+ Vector2D mAcceleration;
+};
+#endif
diff --git a/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.cpp b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.cpp
new file mode 100644
index 0000000..933891a
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.cpp
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+#include "FlockingScene.h"
+
+#include <cstdlib>
+
+#include <Trace.h>
+
+#include <graphics/BasicMeshNode.h>
+#include <graphics/BasicProgram.h>
+#include <graphics/GLUtils.h>
+#include <graphics/Matrix.h>
+#include <graphics/Mesh.h>
+#include <graphics/ProgramNode.h>
+#include <graphics/TransformationNode.h>
+
+static const int FS_NUM_VERTICES = 6;
+
+static const float FS_VERTICES[FS_NUM_VERTICES * 3] = {
+ 1.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, 0.0f,
+ -1.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f };
+
+static const float FS_NORMALS[FS_NUM_VERTICES * 3] = {
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f };
+
+static const float FS_TEX_COORDS[FS_NUM_VERTICES * 2] = {
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f };
+
+static const char* FS_VERTEX =
+ "uniform mat4 u_MVPMatrix;"
+ "uniform mat4 u_MVMatrix;"
+ "attribute vec4 a_Position;"
+ "attribute vec3 a_Normal;"
+ "attribute vec2 a_TexCoordinate;"
+ "varying vec3 v_Position;"
+ "varying vec3 v_Normal;"
+ "varying vec2 v_TexCoordinate;"
+ "void main() {\n"
+ " // Transform the vertex into eye space.\n"
+ " v_Position = vec3(u_MVMatrix * a_Position);\n"
+ " // Pass through the texture coordinate.\n"
+ " v_TexCoordinate = a_TexCoordinate;\n"
+ " // Transform the normal\'s orientation into eye space.\n"
+ " v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));\n"
+ " // Multiply to get the final point in normalized screen coordinates.\n"
+ " gl_Position = u_MVPMatrix * a_Position;\n"
+ "}";
+
+static const char* FS_FRAGMENT =
+ "precision mediump float;"
+ "uniform vec3 u_LightPos;"
+ "uniform sampler2D u_Texture;"
+ "varying vec3 v_Position;"
+ "varying vec3 v_Normal;"
+ "varying vec2 v_TexCoordinate;"
+ "void main() {\n"
+ " // Will be used for attenuation.\n"
+ " float distance = length(u_LightPos - v_Position);\n"
+ " // Get a lighting direction vector from the light to the vertex.\n"
+ " vec3 lightVector = normalize(u_LightPos - v_Position);\n"
+ " // Calculate the dot product of the light vector and vertex normal.\n"
+ " float diffuse = max(dot(v_Normal, lightVector), 0.0);\n"
+ " // Add attenuation.\n"
+ " diffuse = diffuse * (1.0 / (1.0 + (0.01 * distance)));\n"
+ " // Add ambient lighting\n"
+ " diffuse = diffuse + 0.25;\n"
+ " // Multiply the diffuse illumination and texture to get final output color.\n"
+ " gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));\n"
+ "}";
+
+FlockingScene::FlockingScene(int width, int height) :
+ Scene(width, height) {
+ for (int i = 0; i < NUM_BOIDS; i++) {
+ // Generate a boid with a random position.
+ float x = ((rand() % 10) / 5.0f) - 0.1f;
+ float y = ((rand() % 10) / 5.0f) - 0.1f;
+ mBoids[i] = new Boid(x, y);
+ }
+}
+
+Program* FlockingScene::setUpProgram() {
+ // TODO Enable loading programs from file.
+ // mProgramId = GLUtils::loadProgram("flocking");
+ GLuint programId = GLUtils::createProgram(&FS_VERTEX, &FS_FRAGMENT);
+ if (programId == 0) {
+ return NULL;
+ }
+ return new BasicProgram(programId);
+}
+
+Matrix* FlockingScene::setUpModelMatrix() {
+ return new Matrix();
+}
+
+Matrix* FlockingScene::setUpViewMatrix() {
+ // Position the eye in front of the origin.
+ float eyeX = 0.0f;
+ float eyeY = 0.0f;
+ float eyeZ = 2.0f;
+
+ // We are looking at the origin
+ float centerX = 0.0f;
+ float centerY = 0.0f;
+ float centerZ = 0.0f;
+
+ // Set our up vector.
+ float upX = 0.0f;
+ float upY = 1.0f;
+ float upZ = 0.0f;
+
+ // Set the view matrix.
+ return Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
+}
+
+Matrix* FlockingScene::setUpProjectionMatrix() {
+ // Create a new perspective projection matrix. The height will stay the same
+ // while the width will vary as per aspect ratio.
+ mDisplayRatio = ((float) mWidth) / ((float) mHeight);
+ mBoardHeight = 1000.0f;
+ mBoardWidth = mDisplayRatio * mBoardHeight;
+ float left = -mDisplayRatio;
+ float right = mDisplayRatio;
+ float bottom = -1.0f;
+ float top = 1.0f;
+ float near = 1.0f;
+ float far = 3.0f;
+ // Set board dimensions
+
+ return Matrix::newFrustum(left, right, bottom, top, near, far);
+}
+
+bool FlockingScene::setUpTextures() {
+ SCOPED_TRACE();
+ mTextureIds.add(GLUtils::genTexture(256, 256, GLUtils::RANDOM_FILL));
+ mTextureIds.add(GLUtils::genTexture(1, 1, 0xc0c0c0));
+ // TODO Enable loading textures from file.
+ // mTextureIds.add(GLUtils::loadTexture("knight.jpg"));
+ return true;
+}
+
+bool FlockingScene::setUpMeshes() {
+ SCOPED_TRACE();
+ mMeshes.add(new Mesh(FS_VERTICES, FS_NORMALS, FS_TEX_COORDS, FS_NUM_VERTICES));
+ // TODO Enable loading meshes from file.
+ // mMeshes.add(GLUtils::loadMesh("knight.obj", mTextureIds[0]));
+ return true;
+}
+
+bool FlockingScene::tearDown() {
+ SCOPED_TRACE();
+ for (int i = 0; i < NUM_BOIDS; i++) {
+ delete mBoids[i];
+ }
+ return Scene::tearDown();
+}
+
+SceneGraphNode* FlockingScene::updateSceneGraph() {
+ const float MAIN_SCALE = 2.0f; // Scale up as the camera is far away.
+ const float LIMIT_X = mBoardWidth / 2.0f;
+ const float LIMIT_Y = mBoardHeight / 2.0f;
+ SceneGraphNode* sceneGraph = new ProgramNode();
+ Matrix* transformMatrix = Matrix::newScale(MAIN_SCALE * mDisplayRatio, MAIN_SCALE, MAIN_SCALE);
+ TransformationNode* transformNode = new TransformationNode(transformMatrix);
+ sceneGraph->addChild(transformNode);
+ BasicMeshNode* meshNode = new BasicMeshNode(mMeshes[0], mTextureIds[1]);
+ transformNode->addChild(meshNode);
+ for (int i = 0; i < NUM_BOIDS; i++) {
+ Boid* b = mBoids[i];
+ b->flock((const Boid**) &mBoids, NUM_BOIDS, i, LIMIT_X, LIMIT_Y);
+ Vector2D* pos = &(b->mPosition);
+ Vector2D* vel = &(b->mVelocity);
+
+ // Normalize to (-1,1)
+ float x = pos->mX / (LIMIT_X * BOID_SCALE) * mDisplayRatio;
+ float y = pos->mY / (LIMIT_Y * BOID_SCALE);
+
+ // TODO need to include rotation.
+ transformMatrix = Matrix::newScale(BOID_SCALE * MAIN_SCALE, BOID_SCALE * MAIN_SCALE, 1.0f);
+ transformMatrix->translate(x, y, 0.01f);
+ transformNode = new TransformationNode(transformMatrix);
+ sceneGraph->addChild(transformNode);
+ meshNode = new BasicMeshNode(mMeshes[0], mTextureIds[0]);
+ transformNode->addChild(meshNode);
+ }
+ return sceneGraph;
+}
diff --git a/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
new file mode 100644
index 0000000..6433f94
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+#ifndef FLOCKINGSCENE_H
+#define FLOCKINGSCENE_H
+
+#include "../Scene.h"
+#include "Boid.h"
+
+class FlockingScene : public Scene {
+public:
+ FlockingScene(int width, int height);
+ virtual ~FlockingScene() {};
+ bool setUpTextures();
+ bool setUpMeshes();
+ bool tearDown();
+ static const int NUM_BOIDS = 100;
+protected:
+ Program* setUpProgram();
+ Matrix* setUpModelMatrix();
+ Matrix* setUpViewMatrix();
+ Matrix* setUpProjectionMatrix();
+ SceneGraphNode* updateSceneGraph();
+private:
+ Boid* mBoids[NUM_BOIDS];
+ float mDisplayRatio;
+ float mBoardWidth;
+ float mBoardHeight;
+ static const float BOID_SCALE = 1.0f / 50.0f;
+};
+#endif
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java
index 14b247a..9c56e8e 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java
@@ -31,13 +31,16 @@
*/
public class GLReferenceBenchmark extends PtsActivityInstrumentationTestCase2<GLReferenceActivity> {
- private static final int NUM_FRAMES = 100;
+ private static final int NUM_FRAMES_PER_SCENE = 500;
+ private static final int NUM_SCENES = 1;
+ private static final int NUM_FRAMES = NUM_FRAMES_PER_SCENE * NUM_SCENES;
private static final int TIMEOUT = 1000000;
// Reference values collected by averaging across n4, n7, n10.
- private static final double NEXUS_REF_UI_LOAD = 40;// Milliseconds.
- private static final double[] NEXUS_REF_SET_UP = {40, 0, 0, 0};// Milliseconds.
- private static final double NEXUS_REF_UPDATE_AVG = 40;// Milliseconds.
- private static final double NEXUS_REF_RENDER_AVG = 1;// As fraction of display refresh rate.
+ private static final double NEXUS_REF_UI_LOAD = 39.67f;// Milliseconds.
+ // (GL, Context, Textures, Meshes).
+ private static final double[] NEXUS_REF_SET_UP = {22.58f, 44.49f, 2.47f, 0.02f};// MS.
+ private static final double NEXUS_REF_UPDATE_AVG = 9.8f;// MS.
+ private static final double NEXUS_REF_RENDER_AVG = 0.44f;// Fraction of display refresh rate.
public GLReferenceBenchmark() {
super(GLReferenceActivity.class);
@@ -117,10 +120,16 @@
"Set Up Score", setUpScore, ResultType.HIGHER_BETTER, ResultUnit.SCORE);
getReportLog().printArray(
"Update Times", updateTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ getReportLog().printValue(
+ "Update Time Average", updateAverage, ResultType.LOWER_BETTER,
+ ResultUnit.MS);
getReportLog().printValue("Update Score", updateScore, ResultType.HIGHER_BETTER,
ResultUnit.SCORE);
getReportLog().printArray(
"Render Times", renderTimes, ResultType.LOWER_BETTER, ResultUnit.MS);
+ getReportLog().printValue(
+ "Render Time Average", renderAverage, ResultType.LOWER_BETTER,
+ ResultUnit.MS);
getReportLog().printValue("Render Score", renderScore, ResultType.HIGHER_BETTER,
ResultUnit.SCORE);
getReportLog().printValue(
diff --git a/tests/accessibilityservice/res/xml/accessibilityservice.xml b/tests/accessibilityservice/res/xml/accessibilityservice.xml
index 69e0651..6d48f9b 100644
--- a/tests/accessibilityservice/res/xml/accessibilityservice.xml
+++ b/tests/accessibilityservice/res/xml/accessibilityservice.xml
@@ -18,6 +18,6 @@
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault|flagRequestTouchExplorationMode"
android:canRetrieveWindowContent="true"
- android:notificationTimeout="50"
+ android:notificationTimeout="0"
android:settingsActivity="android.accessibilityservice.delegate.SomeActivity"
android:description="@string/title_delegating_accessibility_service" />
diff --git a/tests/src/android/renderscript/cts/global_sync.rs b/tests/src/android/renderscript/cts/global_sync.rs
new file mode 100644
index 0000000..c947fa2
--- /dev/null
+++ b/tests/src/android/renderscript/cts/global_sync.rs
@@ -0,0 +1,32 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+int gInt;
+static int sInt;
+
+rs_allocation aFailed;
+
+void test_global(int expected) {
+ if (gInt != expected) {
+ rsSetElementAt_uchar(aFailed, 1, 0);
+ }
+}
+
+void test_static_global(int expected) {
+ if (sInt != expected) {
+ rsSetElementAt_uchar(aFailed, 1, 0);
+ }
+}
+
+void __attribute__((kernel)) write_global(int ain, uint32_t x) {
+ if (x == 0) {
+ gInt = ain;
+ }
+}
+
+void __attribute__((kernel)) write_static_global(int ain, uint32_t x) {
+ if (x == 0) {
+ sInt = ain;
+ }
+}
+
diff --git a/tests/src/android/renderscript/cts/large_global.rs b/tests/src/android/renderscript/cts/large_global.rs
new file mode 100644
index 0000000..3f2da69
--- /dev/null
+++ b/tests/src/android/renderscript/cts/large_global.rs
@@ -0,0 +1,24 @@
+// 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.
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+char buf[2*1024*1024];
+
+// Never called, just present to ensure that buf does not get optimized away.
+void __attribute__((kernel)) root(char c) {
+ buf[0] = c;
+}
+
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
index a5d92ee..affc9ec 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
@@ -66,7 +66,7 @@
/**
* The timeout after the last accessibility event to consider the device idle.
*/
- public static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 100;
+ public static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 200;
/**
* Instance for detecting the next accessibility event.
@@ -130,9 +130,12 @@
public boolean accept(AccessibilityEvent event) {
final int eventType = event.getEventType();
CharSequence packageName = event.getPackageName();
- Context targetContext = getInstrumentation().getTargetContext();
- return (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
- && targetContext.getPackageName().equals(packageName));
+ // Do not check the package name since an event of this type may
+ // come concurrently from the app and from the IME (since input
+ // focus goes to the first focusable) but we dispatch one event
+ // of each type within a timeout. Hence, sometimes the window
+ // change event from the IME may override the one from the app.
+ return (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
},
TIMEOUT_ASYNC_PROCESSING);
@@ -520,6 +523,8 @@
mEventQueue.clear();
// Prepare to wait for an event.
mWaitingForEventDelivery = true;
+ // We will ignore events from previous interactions.
+ final long executionStartTimeMillis = SystemClock.uptimeMillis();
// Execute the command.
command.run();
try {
@@ -529,11 +534,16 @@
// Drain the event queue
while (!mEventQueue.isEmpty()) {
AccessibilityEvent event = mEventQueue.remove(0);
+
+ // Ignore events from previous interactions.
+ if (event.getEventTime() < executionStartTimeMillis) {
+ continue;
+ }
if (filter.accept(event)) {
return event;
- } else {
- event.recycle();
}
+
+ event.recycle();
}
// Check if timed out and if not wait.
final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 1d28470..ad2dca4 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -113,7 +113,7 @@
assertSame(AccessibilityServiceInfo.DEFAULT
| AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE,
speakingService.flags);
- assertSame(50l, speakingService.notificationTimeout);
+ assertSame(0l, speakingService.notificationTimeout);
assertEquals("Delegating Accessibility Service", speakingService.getDescription());
assertNull(speakingService.packageNames /*all packages*/);
assertNotNull(speakingService.getId());
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index 17c7ebd..c8f8a48 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -1246,6 +1246,261 @@
}
@MediumTest
+ public void testActionNextAndPreviousAtGranularityWordOverEditTextWithContentDescription()
+ throws Exception {
+
+ final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ editText.setText(getString(R.string.foo_bar_baz));
+ editText.setContentDescription(getString(R.string.android_wiki));
+ }
+ });
+
+ final AccessibilityNodeInfo text = getInteractionBridge()
+ .findAccessibilityNodeInfoByTextFromRoot(getString(R.string.foo_bar_baz));
+
+ final int granularities = text.getMovementGranularities();
+ assertEquals(granularities, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+ | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+ | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+ | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+ | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+
+ final Bundle arguments = new Bundle();
+ arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+
+ // Move to the next word and wait for an event.
+ AccessibilityEvent firstExpected = getInteractionBridge()
+ .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
+ @Override
+ public void run() {
+ getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+ }
+ }, new AccessibilityEventFilter() {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ return
+ (event.getEventType() ==
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+ && event.getAction() ==
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+ && event.getPackageName().equals(getActivity().getPackageName())
+ && event.getClassName().equals(EditText.class.getName())
+ && event.getText().size() > 0
+ && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+ && event.getContentDescription().equals(getString(R.string.android_wiki))
+ && event.getFromIndex() == 0
+ && event.getToIndex() == 3
+ && event.getMovementGranularity() ==
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+ }
+ }, TIMEOUT_ASYNC_PROCESSING);
+
+ // Make sure we got the expected event.
+ assertNotNull(firstExpected);
+
+ // Verify the selection position.
+ assertEquals(3, editText.getSelectionStart());
+ assertEquals(3, editText.getSelectionEnd());
+
+ // Move to the next word and wait for an event.
+ AccessibilityEvent secondExpected = getInteractionBridge()
+ .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
+ @Override
+ public void run() {
+ getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+ }
+ }, new AccessibilityEventFilter() {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ return
+ (event.getEventType() ==
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+ && event.getAction() ==
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+ && event.getPackageName().equals(getActivity().getPackageName())
+ && event.getClassName().equals(EditText.class.getName())
+ && event.getText().size() > 0
+ && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+ && event.getContentDescription().equals(getString(R.string.android_wiki))
+ && event.getFromIndex() == 4
+ && event.getToIndex() == 7
+ && event.getMovementGranularity() ==
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+ }
+ }, TIMEOUT_ASYNC_PROCESSING);
+
+ // Make sure we got the expected event.
+ assertNotNull(secondExpected);
+
+ // Verify the selection position.
+ assertEquals(7, editText.getSelectionStart());
+ assertEquals(7, editText.getSelectionEnd());
+
+ // Move to the next word and wait for an event.
+ AccessibilityEvent thirdExpected = getInteractionBridge()
+ .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
+ @Override
+ public void run() {
+ getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
+ }
+ }, new AccessibilityEventFilter() {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ return
+ (event.getEventType() ==
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+ && event.getAction() ==
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+ && event.getPackageName().equals(getActivity().getPackageName())
+ && event.getClassName().equals(EditText.class.getName())
+ && event.getText().size() > 0
+ && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+ && event.getContentDescription().equals(getString(R.string.android_wiki))
+ && event.getFromIndex() == 8
+ && event.getToIndex() == 11
+ && event.getMovementGranularity() ==
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+ }
+ }, TIMEOUT_ASYNC_PROCESSING);
+
+ // Make sure we got the expected event.
+ assertNotNull(thirdExpected);
+
+ // Verify the selection position.
+ assertEquals(11, editText.getSelectionStart());
+ assertEquals(11, editText.getSelectionEnd());
+
+ // Make sure there is no next.
+ assertFalse(getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments));
+
+ // Verify the selection position.
+ assertEquals(11, editText.getSelectionStart());
+ assertEquals(11, editText.getSelectionEnd());
+
+ // Move to the next word and wait for an event.
+ AccessibilityEvent fourthExpected = getInteractionBridge()
+ .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
+ @Override
+ public void run() {
+ getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+ }
+ }, new AccessibilityEventFilter() {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ return
+ (event.getEventType() ==
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+ && event.getAction() ==
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+ && event.getPackageName().equals(getActivity().getPackageName())
+ && event.getClassName().equals(EditText.class.getName())
+ && event.getText().size() > 0
+ && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+ && event.getContentDescription().equals(getString(R.string.android_wiki))
+ && event.getFromIndex() == 8
+ && event.getToIndex() == 11
+ && event.getMovementGranularity() ==
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+ }
+ }, TIMEOUT_ASYNC_PROCESSING);
+
+ // Make sure we got the expected event.
+ assertNotNull(fourthExpected);
+
+ // Verify the selection position.
+ assertEquals(8, editText.getSelectionStart());
+ assertEquals(8, editText.getSelectionEnd());
+
+ // Move to the next word and wait for an event.
+ AccessibilityEvent fifthExpected = getInteractionBridge()
+ .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
+ @Override
+ public void run() {
+ getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+ }
+ }, new AccessibilityEventFilter() {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ return
+ (event.getEventType() ==
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+ && event.getAction() ==
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+ && event.getPackageName().equals(getActivity().getPackageName())
+ && event.getClassName().equals(EditText.class.getName())
+ && event.getText().size() > 0
+ && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+ && event.getContentDescription().equals(getString(R.string.android_wiki))
+ && event.getFromIndex() == 4
+ && event.getToIndex() == 7
+ && event.getMovementGranularity() ==
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+ }
+ }, TIMEOUT_ASYNC_PROCESSING);
+
+ // Make sure we got the expected event.
+ assertNotNull(fifthExpected);
+
+ // Verify the selection position.
+ assertEquals(4, editText.getSelectionStart());
+ assertEquals(4, editText.getSelectionEnd());
+
+ // Move to the next character and wait for an event.
+ AccessibilityEvent sixthExpected = getInteractionBridge()
+ .executeCommandAndWaitForAccessibilityEvent(new Runnable() {
+ @Override
+ public void run() {
+ getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments);
+ }
+ }, new AccessibilityEventFilter() {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ return
+ (event.getEventType() ==
+ AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+ && event.getAction() ==
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+ && event.getPackageName().equals(getActivity().getPackageName())
+ && event.getClassName().equals(EditText.class.getName())
+ && event.getText().size() > 0
+ && event.getText().get(0).toString().equals(getString(R.string.foo_bar_baz))
+ && event.getContentDescription().equals(getString(R.string.android_wiki))
+ && event.getFromIndex() == 0
+ && event.getToIndex() == 3
+ && event.getMovementGranularity() ==
+ AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+ }
+ }, TIMEOUT_ASYNC_PROCESSING);
+
+ // Make sure we got the expected event.
+ assertNotNull(sixthExpected);
+
+ // Verify the selection position.
+ assertEquals(0, editText.getSelectionStart());
+ assertEquals(0, editText.getSelectionEnd());
+
+ // Make sure there is no previous.
+ assertFalse(getInteractionBridge().performAction(text,
+ AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
+
+ // Verify the selection position.
+ assertEquals(0, editText.getSelectionStart());
+ assertEquals(0, editText.getSelectionEnd());
+ }
+
+ @MediumTest
public void testActionNextAndPreviousAtGranularityWordOverTextExtend() throws Exception {
final EditText editText = (EditText) getActivity().findViewById(R.id.edit);
diff --git a/tests/tests/media/res/raw/loudsoftaac.aac b/tests/tests/media/res/raw/loudsoftaac.aac
new file mode 100644
index 0000000..1534ef2
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftaac.aac
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftfaac.m4a b/tests/tests/media/res/raw/loudsoftfaac.m4a
new file mode 100644
index 0000000..b4895b5
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftfaac.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftitunes.m4a b/tests/tests/media/res/raw/loudsoftitunes.m4a
new file mode 100644
index 0000000..b01b36b
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftitunes.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftmp3.mp3 b/tests/tests/media/res/raw/loudsoftmp3.mp3
new file mode 100644
index 0000000..b32c8bd
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftmp3.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftogg.ogg b/tests/tests/media/res/raw/loudsoftogg.ogg
new file mode 100644
index 0000000..dc122d9
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftogg.ogg
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftwav.wav b/tests/tests/media/res/raw/loudsoftwav.wav
new file mode 100644
index 0000000..9930dcb
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftwav.wav
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 54a670d..ab7410b 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -30,17 +30,37 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.zip.CRC32;
public class DecoderTest extends MediaPlayerTestBase {
private static final String TAG = "DecoderTest";
private Resources mResources;
+ short[] mMasterBuffer;
@Override
protected void setUp() throws Exception {
super.setUp();
mResources = mContext.getResources();
+
+ // read master file into memory
+ AssetFileDescriptor masterFd = mResources.openRawResourceFd(R.raw.sinesweepraw);
+ long masterLength = masterFd.getLength();
+ mMasterBuffer = new short[(int) (masterLength / 2)];
+ InputStream is = masterFd.createInputStream();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ for (int i = 0; i < mMasterBuffer.length; i++) {
+ int lo = bis.read();
+ int hi = bis.read();
+ if (hi >= 128) {
+ hi -= 256;
+ }
+ int sample = hi * 256 + lo;
+ mMasterBuffer[i] = (short) sample;
+ }
+ bis.close();
+ masterFd.close();
}
// The allowed errors in the following tests are the actual maximum measured
@@ -48,22 +68,22 @@
// This should allow for some variation in decoders, while still detecting
// phase and delay errors, channel swap, etc.
public void testDecodeMp3Lame() throws Exception {
- decode(R.raw.sinesweepmp3lame, R.raw.sinesweepraw, 804.f);
+ decode(R.raw.sinesweepmp3lame, 804.f);
}
public void testDecodeMp3Smpb() throws Exception {
- decode(R.raw.sinesweepmp3smpb, R.raw.sinesweepraw, 413.f);
+ decode(R.raw.sinesweepmp3smpb, 413.f);
}
public void testDecodeM4a() throws Exception {
- decode(R.raw.sinesweepm4a, R.raw.sinesweepraw, 124.f);
+ decode(R.raw.sinesweepm4a, 124.f);
}
public void testDecodeOgg() throws Exception {
- decode(R.raw.sinesweepogg, R.raw.sinesweepraw, 168.f);
+ decode(R.raw.sinesweepogg, 168.f);
}
public void testDecodeWav() throws Exception {
- decode(R.raw.sinesweepwav, R.raw.sinesweepraw, 0.0f);
+ decode(R.raw.sinesweepwav, 0.0f);
}
public void testDecodeFlac() throws Exception {
- decode(R.raw.sinesweepflac, R.raw.sinesweepraw, 0.0f);
+ decode(R.raw.sinesweepflac, 0.0f);
}
/**
@@ -72,25 +92,30 @@
* @param maxerror the maximum allowed root mean squared error
* @throws IOException
*/
- private void decode(int testinput, int master, float maxerror) throws IOException {
+ private void decode(int testinput, float maxerror) throws IOException {
- // read master file into memory
- AssetFileDescriptor masterFd = mResources.openRawResourceFd(master);
- long masterLength = masterFd.getLength();
- short[] masterBuffer = new short[(int) (masterLength / 2)];
- InputStream is = masterFd.createInputStream();
- BufferedInputStream bis = new BufferedInputStream(is);
- for (int i = 0; i < masterBuffer.length; i++) {
- int lo = bis.read();
- int hi = bis.read();
- if (hi >= 128) {
- hi -= 256;
- }
- int sample = hi * 256 + lo;
- masterBuffer[i] = (short) sample;
+ short [] decoded = decodeToMemory(testinput);
+
+ assertEquals("wrong data size", mMasterBuffer.length, decoded.length);
+
+ long totalErrorSquared = 0;
+
+ for (int i = 0; i < decoded.length; i++) {
+ short sample = decoded[i];
+ short mastersample = mMasterBuffer[i];
+ int d = sample - mastersample;
+ totalErrorSquared += d * d;
}
- bis.close();
- masterFd.close();
+
+ long avgErrorSquared = (totalErrorSquared / decoded.length);
+ double rmse = Math.sqrt(avgErrorSquared);
+ assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
+ }
+
+ private short[] decodeToMemory(int testinput) throws IOException {
+
+ short [] decoded = new short[1024];
+ int decodedIdx = 0;
AssetFileDescriptor testFd = mResources.openRawResourceFd(testinput);
@@ -118,9 +143,6 @@
extractor.selectTrack(0);
// start decoding
- int numBytesDecoded = 0;
- int maxdelta = 0;
- long totalErrorSquared = 0;
final long kTimeOutUs = 5000;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
boolean sawInputEOS = false;
@@ -164,17 +186,13 @@
int outputBufIndex = res;
ByteBuffer buf = codecOutputBuffers[outputBufIndex];
- // check the waveform matches within the specified max error
- for (int i = 0; i < info.size; i += 2) {
- short sample = buf.getShort(i);
- int idx = (numBytesDecoded + i) / 2;
- assertTrue("decoder returned too much data", idx < masterBuffer.length);
- short mastersample = masterBuffer[idx];
- int d = sample - mastersample;
- totalErrorSquared += d * d;
+ if (decodedIdx + (info.size / 2) >= decoded.length) {
+ decoded = Arrays.copyOf(decoded, decodedIdx + (info.size / 2));
}
- numBytesDecoded += info.size;
+ for (int i = 0; i < info.size; i += 2) {
+ decoded[decodedIdx++] = buf.getShort(i);
+ }
codec.releaseOutputBuffer(outputBufIndex, false /* render */);
@@ -195,11 +213,7 @@
codec.stop();
codec.release();
-
- assertEquals("wrong data size", masterLength, numBytesDecoded);
- long avgErrorSquared = (totalErrorSquared / (numBytesDecoded / 2));
- double rmse = Math.sqrt(avgErrorSquared);
- assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
+ return decoded;
}
public void testCodecBasicH264() throws Exception {
@@ -691,5 +705,110 @@
return crc.getValue();
}
+ public void testFlush() throws Exception {
+ testFlush(R.raw.loudsoftwav);
+ testFlush(R.raw.loudsoftogg);
+ testFlush(R.raw.loudsoftmp3);
+ testFlush(R.raw.loudsoftaac);
+ testFlush(R.raw.loudsoftfaac);
+ testFlush(R.raw.loudsoftitunes);
+ }
+
+ private void testFlush(int resource) throws Exception {
+
+ AssetFileDescriptor testFd = mResources.openRawResourceFd(resource);
+
+ MediaExtractor extractor;
+ MediaCodec codec;
+ ByteBuffer[] codecInputBuffers;
+ ByteBuffer[] codecOutputBuffers;
+
+ extractor = new MediaExtractor();
+ extractor.setDataSource(testFd.getFileDescriptor(), testFd.getStartOffset(),
+ testFd.getLength());
+ testFd.close();
+
+ assertEquals("wrong number of tracks", 1, extractor.getTrackCount());
+ MediaFormat format = extractor.getTrackFormat(0);
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ assertTrue("not an audio file", mime.startsWith("audio/"));
+
+ codec = MediaCodec.createDecoderByType(mime);
+ codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
+ codec.start();
+ codecInputBuffers = codec.getInputBuffers();
+ codecOutputBuffers = codec.getOutputBuffers();
+
+ extractor.selectTrack(0);
+
+ // decode a bit of the first part of the file, and verify the amplitude
+ short maxvalue1 = getAmplitude(extractor, codec);
+
+ // flush the codec and seek the extractor a different position, then decode a bit more
+ // and check the amplitude
+ extractor.seekTo(8000000, 0);
+ codec.flush();
+ short maxvalue2 = getAmplitude(extractor, codec);
+
+ assertTrue(maxvalue1 > 20000);
+ assertTrue(maxvalue2 < 5000);
+ codec.stop();
+ codec.release();
+
+ }
+
+ private short getAmplitude(MediaExtractor extractor, MediaCodec codec) {
+ short maxvalue = 0;
+ int numBytesDecoded = 0;
+ final long kTimeOutUs = 5000;
+ ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
+ ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+
+ while(numBytesDecoded < 44100 * 2) {
+ int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
+
+ if (inputBufIndex >= 0) {
+ ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+
+ int sampleSize = extractor.readSampleData(dstBuf, 0 /* offset */);
+ long presentationTimeUs = extractor.getSampleTime();
+
+ codec.queueInputBuffer(
+ inputBufIndex,
+ 0 /* offset */,
+ sampleSize,
+ presentationTimeUs,
+ 0 /* flags */);
+
+ extractor.advance();
+ }
+ int res = codec.dequeueOutputBuffer(info, kTimeOutUs);
+
+ if (res >= 0) {
+
+ int outputBufIndex = res;
+ ByteBuffer buf = codecOutputBuffers[outputBufIndex];
+
+ for (int i = 0; i < info.size; i += 2) {
+ short sample = buf.getShort(i);
+ if (maxvalue < sample) {
+ maxvalue = sample;
+ }
+ int idx = (numBytesDecoded + i) / 2;
+ }
+
+ numBytesDecoded += info.size;
+
+ codec.releaseOutputBuffer(outputBufIndex, false /* render */);
+ } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+ codecOutputBuffers = codec.getOutputBuffers();
+ } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+ MediaFormat oformat = codec.getOutputFormat();
+ }
+ }
+ return maxvalue;
+ }
+
}
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index b44321c..42ae7a7 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -295,7 +295,7 @@
* makes sure the samples match.
*/
private void verifySamplesMatch(int srcMedia, String testMediaPath,
- int seekToUs) {
+ int seekToUs) throws IOException {
AssetFileDescriptor testFd = mResources.openRawResourceFd(srcMedia);
MediaExtractor extractorSrc = new MediaExtractor();
extractorSrc.setDataSource(testFd.getFileDescriptor(),
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index 4fa69a8..c244159 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -23,6 +23,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
+import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkInfo.State;
@@ -30,7 +31,10 @@
import android.test.AndroidTestCase;
import android.util.Log;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -51,6 +55,9 @@
private ConnectivityManager mCm;
private WifiManager mWifiManager;
private PackageManager mPackageManager;
+ private final HashMap<Integer, NetworkConfig> mNetworks =
+ new HashMap<Integer, NetworkConfig>();
+ private final List<Integer>mProtectedNetworks = new ArrayList<Integer>();
@Override
protected void setUp() throws Exception {
@@ -58,45 +65,115 @@
mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
mPackageManager = getContext().getPackageManager();
- }
- public void testGetNetworkInfo() {
- assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES);
- NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI);
- if (ni != null) {
- State state = ni.getState();
- assertTrue(State.UNKNOWN.ordinal() >= state.ordinal()
- && state.ordinal() >= State.CONNECTING.ordinal());
- DetailedState ds = ni.getDetailedState();
- assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal()
- && ds.ordinal() >= DetailedState.IDLE.ordinal());
+ String[] naStrings = getContext().getResources().getStringArray(
+ com.android.internal.R.array.networkAttributes);
+ for (String naString : naStrings) {
+ try {
+ NetworkConfig n = new NetworkConfig(naString);
+ mNetworks.put(n.type, n);
+ } catch (Exception e) {}
}
- ni = mCm.getNetworkInfo(TYPE_MOBILE);
- if (ni != null) {
- State state = ni.getState();
- assertTrue(State.UNKNOWN.ordinal() >= state.ordinal()
- && state.ordinal() >= State.CONNECTING.ordinal());
- DetailedState ds = ni.getDetailedState();
- assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal()
- && ds.ordinal() >= DetailedState.IDLE.ordinal());
+
+ int[] protectedNetworks = getContext().getResources().getIntArray(
+ com.android.internal.R.array.config_protectedNetworks);
+ for (int p : protectedNetworks) {
+ mProtectedNetworks.add(p);
}
- ni = mCm.getNetworkInfo(-1);
- assertNull(ni);
}
public void testIsNetworkTypeValid() {
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_MMS));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_SUPL));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_DUN));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_HIPRI));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIMAX));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_BLUETOOTH));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_DUMMY));
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_ETHERNET));
+ assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_FOTA));
+ assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS));
+ assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS));
+ assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P));
+ assertFalse(mCm.isNetworkTypeValid(-1));
+ assertTrue(mCm.isNetworkTypeValid(0));
+ assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE));
+ assertFalse(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE+1));
NetworkInfo[] ni = mCm.getAllNetworkInfo();
- for (NetworkInfo n : ni) {
+ for (NetworkInfo n: ni) {
assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType()));
}
- assertFalse(ConnectivityManager.isNetworkTypeValid(-1));
+
+ }
+
+ public void testSetNetworkPreference() {
+ // verify swtiching between two default networks - need to connectable networks though
+ // could use test and whatever the current active network is
+ NetworkInfo active = mCm.getActiveNetworkInfo();
+ int originalPref = mCm.getNetworkPreference();
+ int currentPref = originalPref;
+ for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
+ mCm.setNetworkPreference(type);
+ NetworkConfig c = mNetworks.get(type);
+ boolean expectWorked = (c != null && c.isDefault());
+ try {
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException e) {}
+ int foundType = mCm.getNetworkPreference();
+ if (expectWorked) {
+ assertTrue("We should have been able to switch prefered type " + type,
+ foundType == type);
+ currentPref = foundType;
+ } else {
+ assertTrue("We should not have been able to switch type " + type,
+ foundType == currentPref);
+ }
+ }
+ mCm.setNetworkPreference(originalPref);
+ }
+
+ public void testGetActiveNetworkInfo() {
+ NetworkInfo ni = mCm.getActiveNetworkInfo();
+
+ assertTrue("You must have an active network connection to complete CTS", ni != null);
+ assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
+ assertTrue(ni.getState() == State.CONNECTED);
+ }
+
+ public void testGetNetworkInfo() {
+ for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
+ if (isSupported(type)) {
+ NetworkInfo ni = mCm.getNetworkInfo(type);
+ assertTrue("Info shouldn't be null for " + type, ni != null);
+ State state = ni.getState();
+ assertTrue("Bad state for " + type, State.UNKNOWN.ordinal() >= state.ordinal()
+ && state.ordinal() >= State.CONNECTING.ordinal());
+ DetailedState ds = ni.getDetailedState();
+ assertTrue("Bad detailed state for " + type,
+ DetailedState.FAILED.ordinal() >= ds.ordinal()
+ && ds.ordinal() >= DetailedState.IDLE.ordinal());
+ } else {
+ assertNull("Info should be null for " + type, mCm.getNetworkInfo(type));
+ }
+ }
}
public void testGetAllNetworkInfo() {
NetworkInfo[] ni = mCm.getAllNetworkInfo();
assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES);
+ for (int type = 0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
+ int desiredFoundCount = (isSupported(type) ? 1 : 0);
+ int foundCount = 0;
+ for (NetworkInfo i : ni) {
+ if (i.getType() == type) foundCount++;
+ }
+ assertTrue("Unexpected foundCount of " + foundCount + " for type " + type,
+ foundCount == desiredFoundCount);
+ }
}
public void testStartUsingNetworkFeature() {
@@ -130,35 +207,46 @@
}
}
- public void testRequestRouteToHost() {
- Set<Integer> exceptionFreeTypes = new HashSet<Integer>();
- exceptionFreeTypes.add(ConnectivityManager.TYPE_BLUETOOTH);
- exceptionFreeTypes.add(ConnectivityManager.TYPE_ETHERNET);
- exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE);
- exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_DUN);
- exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_HIPRI);
- exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_MMS);
- exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_SUPL);
+ private boolean isSupported(int networkType) {
+ return mNetworks.containsKey(networkType);
+ }
- NetworkInfo[] ni = mCm.getAllNetworkInfo();
- for (NetworkInfo n : ni) {
- if (n.isConnected() && exceptionFreeTypes.contains(n.getType())) {
- assertTrue("Network type: " + n.getType(), mCm.requestRouteToHost(n.getType(),
- HOST_ADDRESS));
+ // true if only the system can turn it on
+ private boolean isNetworkProtected(int networkType) {
+ return mProtectedNetworks.contains(networkType);
+ }
+
+ public void testIsNetworkSupported() {
+ for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
+ boolean supported = mCm.isNetworkSupported(type);
+ if (isSupported(type)) {
+ assertTrue(supported);
+ } else {
+ assertFalse(supported);
}
}
+ }
+
+ public void testRequestRouteToHost() {
+ for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
+ NetworkInfo ni = mCm.getNetworkInfo(type);
+ boolean expectToWork = isSupported(type) && !isNetworkProtected(type) &&
+ ni != null && ni.isConnected();
+
+ try {
+ assertTrue("Network type " + type,
+ mCm.requestRouteToHost(type, HOST_ADDRESS) == expectToWork);
+ } catch (Exception e) {
+ Log.d(TAG, "got exception in requestRouteToHost for type " + type);
+ assertFalse("Exception received for type " + type, expectToWork);
+ }
+
+ //TODO verify route table
+ }
assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS));
}
- public void testGetActiveNetworkInfo() {
- NetworkInfo ni = mCm.getActiveNetworkInfo();
-
- if (ni != null) {
- assertTrue(ni.getType() >= 0);
- }
- }
-
public void testTest() {
mCm.getBackgroundDataSetting();
}
@@ -197,12 +285,16 @@
assertTrue("Couldn't requestRouteToHost using HIPRI.",
mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS));
-
+ // TODO check dns selection
+ // TODO check routes
} catch (InterruptedException e) {
fail("Broadcast receiver waiting for ConnectivityManager interrupted.");
} finally {
mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
FEATURE_ENABLE_HIPRI);
+ // TODO wait for HIPRI to go
+ // TODO check dns selection
+ // TODO check routes
if (!isWifiConnected) {
mWifiManager.setWifiEnabled(false);
}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
new file mode 100644
index 0000000..a684e41
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.provider.cts;
+
+import static android.provider.ContactsContract.CommonDataKinds;
+import static android.provider.ContactsContract.DataUsageFeedback;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.cts.contacts.DataUtil;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.RawContactUtil;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+
+public class ContactsContract_DataUsageTest extends AndroidTestCase {
+
+ private ContentResolver mResolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = getContext().getContentResolver();
+ }
+
+ public void testSingleDataUsageFeedback_incrementsCorrectDataItems() {
+ DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+ long[] dataIds = setupRawContactDataItems(ids.mRawContactId);
+
+ // Update just 1 data item at a time.
+ updateDataUsageAndAssert(dataIds[1], 1);
+ updateDataUsageAndAssert(dataIds[1], 2);
+
+ updateDataUsageAndAssert(dataIds[2], 1);
+ updateDataUsageAndAssert(dataIds[2], 2);
+ updateDataUsageAndAssert(dataIds[2], 3);
+
+ // Go back and update the previous data item again.
+ updateDataUsageAndAssert(dataIds[1], 3);
+
+ deleteDataUsage();
+ RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+ }
+
+ public void testMultiIdDataUsageFeedback_incrementsCorrectDataItems() {
+ DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+ long[] dataIds = setupRawContactDataItems(ids.mRawContactId);
+
+ assertDataUsageEquals(dataIds, 0, 0, 0, 0);
+
+ updateMultipleAndAssertUpdateSuccess(new long[] {dataIds[1], dataIds[2]});
+ assertDataUsageEquals(dataIds, 0, 1, 1, 0);
+
+ updateMultipleAndAssertUpdateSuccess(new long[]{dataIds[1], dataIds[2]});
+ assertDataUsageEquals(dataIds, 0, 2, 2, 0);
+
+ updateDataUsageAndAssert(dataIds[1], 3);
+ assertDataUsageEquals(dataIds, 0, 3, 2, 0);
+
+ updateMultipleAndAssertUpdateSuccess(new long[]{dataIds[0], dataIds[1]});
+ assertDataUsageEquals(dataIds, 1, 4, 2, 0);
+
+ deleteDataUsage();
+ RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+ }
+
+ private long[] setupRawContactDataItems(long rawContactId) {
+ // Create 4 data items.
+ long[] dataIds = new long[4];
+
+ ContentValues values = new ContentValues();
+ values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+ values.put(CommonDataKinds.Phone.NUMBER, "555-5555");
+ dataIds[0] = DataUtil.insertData(mResolver, rawContactId, values);
+
+ values.clear();
+ values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+ values.put(CommonDataKinds.Phone.NUMBER, "555-5554");
+ dataIds[1] = DataUtil.insertData(mResolver, rawContactId, values);
+
+ values.clear();
+ values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE);
+ values.put(CommonDataKinds.Email.ADDRESS, "test@thisisfake.com");
+ dataIds[2] = DataUtil.insertData(mResolver, rawContactId, values);
+
+ values.clear();
+ values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE);
+ values.put(CommonDataKinds.Phone.NUMBER, "555-5556");
+ dataIds[3] = DataUtil.insertData(mResolver, rawContactId, values);
+
+ return dataIds;
+ }
+
+ /**
+ * Updates multiple data ids at once. And asserts the update returned success.
+ */
+ private void updateMultipleAndAssertUpdateSuccess(long[] dataIds) {
+ String[] ids = new String[dataIds.length];
+ for (int i = 0; i < dataIds.length; i++) {
+ ids[i] = String.valueOf(dataIds[i]);
+ }
+ Uri uri = DataUsageFeedback.FEEDBACK_URI.buildUpon().appendPath(TextUtils.join(",", ids))
+ .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
+ DataUsageFeedback.USAGE_TYPE_CALL).build();
+ int result = mResolver.update(uri, new ContentValues(), null, null);
+ assertTrue(result > 0);
+ }
+
+ /**
+ * Updates a single data item usage. Asserts the update was successful. Asserts the usage
+ * number is equal to expected value.
+ */
+ private void updateDataUsageAndAssert(long dataId, int assertValue) {
+ Uri uri = DataUsageFeedback.FEEDBACK_URI.buildUpon().appendPath(String.valueOf(dataId))
+ .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
+ DataUsageFeedback.USAGE_TYPE_CALL).build();
+ int result = mResolver.update(uri, new ContentValues(), null, null);
+ assertTrue(result > 0);
+
+ assertDataUsageEquals(dataId, assertValue);
+ }
+
+ /**
+ * Assert that the given data ids have usage values in the respective order.
+ */
+ private void assertDataUsageEquals(long[] dataIds, int... expectedValues) {
+ if (dataIds.length != expectedValues.length) {
+ throw new IllegalArgumentException("dataIds and expectedValues must be the same size");
+ }
+
+ for (int i = 0; i < dataIds.length; i++) {
+ assertDataUsageEquals(dataIds[i], expectedValues[i]);
+ }
+ }
+
+ /**
+ * Assert a single data item has a specific usage value.
+ */
+ private void assertDataUsageEquals(long dataId, int expectedValue) {
+ // Query and assert value is expected.
+ String[] projection = new String[]{ContactsContract.Data.TIMES_USED};
+ String[] record = DataUtil.queryById(mResolver, dataId, projection);
+ assertNotNull(record);
+ long actual = 0;
+ // Tread null as 0
+ if (record[0] != null) {
+ actual = Long.parseLong(record[0]);
+ }
+ assertEquals(expectedValue, actual);
+ }
+
+ private void deleteDataUsage() {
+ mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null);
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
index adb253c..ae2812e 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
@@ -19,6 +19,7 @@
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
+import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
@@ -29,6 +30,12 @@
private static final Uri URI = ContactsContract.Data.CONTENT_URI;
+ public static String[] queryById(ContentResolver resolver, long dataId, String[] projection) {
+ Uri uri = ContentUris.withAppendedId(URI, dataId);
+ Cursor cursor = resolver.query(uri, projection, null, null, null);
+ return CommonDatabaseUtils.singleRecordToArray(cursor);
+ }
+
public static void insertName(ContentResolver resolver, long rawContactId) {
ContentValues values = new ContentValues();
values.put(ContactsContract.Data.MIMETYPE,
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
index 8f9e7bd5..c87dc01 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
@@ -49,14 +49,13 @@
ContentValues values = new ContentValues();
values.put(ContactsContract.RawContacts.ACCOUNT_NAME, StaticAccountAuthenticator.NAME);
values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, StaticAccountAuthenticator.TYPE);
- Uri uri = resolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
+ Uri uri = resolver.insert(URI, values);
return ContentUris.parseId(uri);
}
public static String[] queryByRawContactId(ContentResolver resolver,
long rawContactId, String[] projection) {
- Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
- rawContactId);
+ Uri uri = ContentUris.withAppendedId(URI, rawContactId);
Cursor cursor = resolver.query(uri, projection, null, null, null);
return CommonDatabaseUtils.singleRecordToArray(cursor);
}
@@ -68,14 +67,14 @@
*/
public static List<String[]> queryByContactId(ContentResolver resolver, long contactId,
String[] projection) {
- Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, contactId);
+ Uri uri = ContentUris.withAppendedId(URI, contactId);
Cursor cursor = resolver.query(uri, projection, null, null, null);
return CommonDatabaseUtils.multiRecordToArray(cursor);
}
public static void delete(ContentResolver resolver, long rawContactId,
boolean isSyncAdapter) {
- Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId)
+ Uri uri = ContentUris.withAppendedId(URI, rawContactId)
.buildUpon()
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, isSyncAdapter + "")
.build();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GlobalSync.java b/tests/tests/renderscript/src/android/renderscript/cts/GlobalSync.java
new file mode 100644
index 0000000..f895661
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GlobalSync.java
@@ -0,0 +1,88 @@
+/*
+ * 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.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+
+public class GlobalSync extends RSBaseCompute {
+ Allocation AFailed;
+ int [] Failed;
+ Allocation AIn;
+
+ protected void setupGlobalSync(RenderScript mRS, ScriptC_global_sync gs, int v) {
+ Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+ Type t = typeBuilder.setX(1).create();
+
+ AFailed = Allocation.createTyped(mRS, t);
+ Failed = new int [1];
+ Failed[0] = 0;
+ AFailed.copyFrom(Failed);
+ gs.set_aFailed(AFailed);
+
+ AIn = Allocation.createTyped(mRS, t);
+ int [] In = new int [1];
+ In[0] = v;
+ AIn.copyFrom(In);
+
+ }
+
+ /**
+ * Test whether we are properly synchronizing extern global data
+ * when dealing with mixed kernels/invokables.
+ */
+ public void testGlobalSync() {
+ ScriptC_global_sync gs = new ScriptC_global_sync(mRS);
+
+ int v = 7;
+ setupGlobalSync(mRS, gs, v);
+ gs.forEach_write_global(AIn);
+ gs.invoke_test_global(v);
+
+ AFailed.copyTo(Failed);
+ if (Failed[0] != 0) {
+ FoundError = true;
+ }
+
+ gs.destroy();
+ checkForErrors();
+ }
+
+ /**
+ * Test whether we are properly synchronizing static global data
+ * when dealing with mixed kernels/invokables.
+ */
+ public void testStaticGlobalSync() {
+ ScriptC_global_sync gs = new ScriptC_global_sync(mRS);
+
+ int v = 9;
+ setupGlobalSync(mRS, gs, v);
+ gs.forEach_write_static_global(AIn);
+ gs.invoke_test_static_global(v);
+
+ AFailed.copyTo(Failed);
+ if (Failed[0] != 0) {
+ FoundError = true;
+ }
+
+ gs.destroy();
+ checkForErrors();
+ }
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GlobalTest.java b/tests/tests/renderscript/src/android/renderscript/cts/GlobalTest.java
new file mode 100644
index 0000000..b0c3b63
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GlobalTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.renderscript.cts;
+
+public class GlobalTest extends RSBaseCompute {
+ /**
+ * Test whether we properly clean up after large global arrays are
+ * allocated/deallocated.
+ */
+ public void testLargeGlobal() {
+ for (int i = 0; i < 1000; i++) {
+ ScriptC_large_global lg = new ScriptC_large_global(mRS);
+ lg.destroy();
+ }
+ checkForErrors();
+ }
+}
diff --git a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
index 52f0d3f..14e01e8 100644
--- a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
@@ -189,11 +189,11 @@
fixedTime, java.text.DateFormat.SHORT, java.text.DateFormat.FULL));
final long HOUR_DURATION = 2 * 60 * 60 * 1000;
- assertEquals("5:30:15 AM GMT", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
+ assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.FULL));
assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.DEFAULT));
- assertEquals("5:30:15 AM GMT", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
+ assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.LONG));
assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.MEDIUM));