summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java8
-rw-r--r--tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java10
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java20
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java20
-rw-r--r--tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java2
-rw-r--r--tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java11
-rw-r--r--tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java9
-rw-r--r--tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java12
-rw-r--r--tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java2
-rw-r--r--tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java14
-rw-r--r--tests/DynamicDrawableTest/Android.mk26
-rw-r--r--tests/DynamicDrawableTest/AndroidManifest.xml99
-rw-r--r--tests/DynamicDrawableTest/lint.xml3
-rw-r--r--tests/DynamicDrawableTest/res/drawable-hdpi/icon.pngbin0 -> 5141 bytes
-rw-r--r--tests/DynamicDrawableTest/res/drawable/icon.pngbin0 -> 3133 bytes
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml73
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml46
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml137
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml126
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml147
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml76
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml45
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml48
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml41
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml114
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml62
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml90
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml82
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml54
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml48
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml46
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml46
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml45
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml45
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml37
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml33
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml29
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_test01.xml31
-rw-r--r--tests/DynamicDrawableTest/res/drawable/vector_test02.xml31
-rw-r--r--tests/DynamicDrawableTest/res/values/strings.xml18
-rw-r--r--tests/DynamicDrawableTest/res/values/styles.xml16
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java69
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java89
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java43
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java95
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java36
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java152
-rw-r--r--tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java25
-rw-r--r--tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java8
-rw-r--r--tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java14
-rw-r--r--tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java5
-rw-r--r--tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java4
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml27
-rw-r--r--tests/HwAccelerationTest/res/layout/isolation.xml56
-rw-r--r--tests/HwAccelerationTest/res/layout/projection.xml37
-rw-r--r--tests/HwAccelerationTest/res/values/styles.xml34
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java180
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java12
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java83
-rw-r--r--tests/IdleServiceTest/Android.mk13
-rw-r--r--tests/IdleServiceTest/AndroidManifest.xml59
-rw-r--r--tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java52
-rw-r--r--tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java48
-rw-r--r--tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java36
-rw-r--r--tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java38
-rw-r--r--tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java6
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java34
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java14
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java14
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java16
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java14
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java4
-rw-r--r--tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java26
-rw-r--r--tests/OneMedia/Android.mk18
-rw-r--r--tests/OneMedia/AndroidManifest.xml30
-rw-r--r--tests/OneMedia/res/drawable-hdpi/ic_launcher.pngbin0 -> 7658 bytes
-rw-r--r--tests/OneMedia/res/drawable-mdpi/ic_launcher.pngbin0 -> 3777 bytes
-rw-r--r--tests/OneMedia/res/drawable-xhdpi/ic_launcher.pngbin0 -> 12516 bytes
-rw-r--r--tests/OneMedia/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 24777 bytes
-rw-r--r--tests/OneMedia/res/layout/activity_main.xml16
-rw-r--r--tests/OneMedia/res/layout/activity_one_player.xml61
-rw-r--r--tests/OneMedia/res/menu/main.xml9
-rw-r--r--tests/OneMedia/res/values/colors.xml22
-rw-r--r--tests/OneMedia/res/values/dimens.xml9
-rw-r--r--tests/OneMedia/res/values/strings.xml15
-rw-r--r--tests/OneMedia/res/values/styles.xml44
-rw-r--r--tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl22
-rw-r--r--tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl29
-rw-r--r--tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java168
-rw-r--r--tests/OneMedia/src/com/android/onemedia/OnePlayerService.java42
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerController.java209
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerService.java157
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerSession.java209
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl22
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java704
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java59
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java10
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/Renderer.java199
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java22
-rw-r--r--tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java53
-rw-r--r--tests/RenderThreadTest/Android.mk18
-rw-r--r--tests/RenderThreadTest/AndroidManifest.xml29
-rw-r--r--tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.pngbin0 -> 9397 bytes
-rw-r--r--tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.pngbin0 -> 5237 bytes
-rw-r--r--tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.pngbin0 -> 14383 bytes
-rw-r--r--tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpgbin0 -> 561519 bytes
-rw-r--r--tests/RenderThreadTest/res/layout/activity_main.xml12
-rw-r--r--tests/RenderThreadTest/res/layout/activity_sub.xml39
-rw-r--r--tests/RenderThreadTest/res/layout/item_layout.xml12
-rw-r--r--tests/RenderThreadTest/res/values/strings.xml8
-rw-r--r--tests/RenderThreadTest/res/values/styles.xml11
-rw-r--r--tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java158
-rw-r--r--tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java60
-rw-r--r--tests/SharedLibrary/client/Android.mk2
-rw-r--r--tests/SharedLibrary/client/AndroidManifest.xml2
-rw-r--r--tests/SharedLibrary/client/res/layout/main.xml25
-rw-r--r--tests/SharedLibrary/client/res/values/strings.xml1
-rw-r--r--tests/SharedLibrary/client/res/values/themes.xml6
-rw-r--r--tests/SharedLibrary/client/src/com/google/android/test/lib_client/ActivityMain.java23
-rw-r--r--tests/SharedLibrary/lib/Android.mk7
-rw-r--r--tests/SharedLibrary/lib/proguard.proguard7
-rw-r--r--tests/SharedLibrary/lib/res/layout/address.xml16
-rw-r--r--tests/SharedLibrary/lib/res/values/attrs.xml13
-rw-r--r--tests/SharedLibrary/lib/res/values/public.xml17
-rw-r--r--tests/SharedLibrary/lib/res/values/strings.xml9
-rw-r--r--tests/SharedLibrary/lib/res/values/themes.xml18
-rw-r--r--tests/SharedLibrary/lib/src/com/google/android/test/shared_library/AddressView.java44
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java4
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java8
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java4
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java7
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java2
135 files changed, 5816 insertions, 107 deletions
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
index daec845..8189fa9 100644
--- a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
@@ -30,6 +30,7 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
+import java.io.IOException;
import java.nio.ByteBuffer;
public class DisplaySinkService extends Service implements SurfaceHolder.Callback {
@@ -150,7 +151,12 @@ public class DisplaySinkService extends Service implements SurfaceHolder.Callbac
if (mSurface != null) {
MediaFormat format = MediaFormat.createVideoFormat(
"video/avc", mSurfaceWidth, mSurfaceHeight);
- mCodec = MediaCodec.createDecoderByType("video/avc");
+ try {
+ mCodec = MediaCodec.createDecoderByType("video/avc");
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "failed to create video/avc decoder", e);
+ }
mCodec.configure(format, mSurface, null, 0);
mCodec.start();
mCodecBufferInfo = new BufferInfo();
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
index 256f900..a4faca5 100644
--- a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
@@ -32,6 +32,7 @@ import android.os.Message;
import android.view.Display;
import android.view.Surface;
+import java.io.IOException;
import java.nio.ByteBuffer;
public class DisplaySourceService extends Service {
@@ -191,8 +192,13 @@ public class DisplaySourceService extends Service {
format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL);
-
- MediaCodec codec = MediaCodec.createEncoderByType("video/avc");
+ MediaCodec codec;
+ try {
+ codec = MediaCodec.createEncoderByType("video/avc");
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "failed to create video/avc encoder", e);
+ }
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Surface surface = codec.createInputSurface();
codec.start();
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
index 2b5e674..ea08a6a 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
@@ -22,11 +22,25 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.GridLayout;
-import android.widget.*;
+import android.widget.Space;
+import android.widget.TextView;
-import static android.text.InputType.*;
-import static android.widget.GridLayout.*;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.widget.GridLayout.ALIGN_BOUNDS;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.START;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.spec;
public class BiDiTestGridLayoutCodeLtr extends Fragment {
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
index 3a03c6c..fc3a92c 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
@@ -22,11 +22,25 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.GridLayout;
-import android.widget.*;
+import android.widget.Space;
+import android.widget.TextView;
-import static android.text.InputType.*;
-import static android.widget.GridLayout.*;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.widget.GridLayout.ALIGN_BOUNDS;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.START;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.spec;
public class BiDiTestGridLayoutCodeRtl extends Fragment {
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
index ef885e3..ec02d34 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
@@ -117,7 +117,7 @@ public class GraphReader {
}
@Override
- public void execute(CommandStack stack) {
+ public void execute(CommandStack stack) {
Filter filter = null;
try {
filter = stack.getFactory().createFilterByClassName(mClassName,
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java
index 0219fd7..3b3de9f 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java
@@ -59,8 +59,15 @@ public class AudioTrackDecoder extends TrackDecoder {
@Override
protected MediaCodec initMediaCodec(MediaFormat format) {
- MediaCodec mediaCodec = MediaCodec.createDecoderByType(
- format.getString(MediaFormat.KEY_MIME));
+ MediaCodec mediaCodec;
+ try {
+ mediaCodec = MediaCodec.createDecoderByType(
+ format.getString(MediaFormat.KEY_MIME));
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "failed to create decoder for "
+ + format.getString(MediaFormat.KEY_MIME), e);
+ }
mediaCodec.configure(format, null, null, 0);
return mediaCodec;
}
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java
index 96f3059..a624010 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java
@@ -29,6 +29,7 @@ import androidx.media.filterfw.Frame;
import androidx.media.filterfw.FrameImage2D;
import androidx.media.filterfw.PixelUtils;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashSet;
@@ -214,7 +215,13 @@ public class CpuVideoTrackDecoder extends VideoTrackDecoder {
return null;
} else {
String bestCodec = candidateCodecs.firstEntry().getValue();
- return MediaCodec.createByCodecName(bestCodec);
+ try {
+ return MediaCodec.createByCodecName(bestCodec);
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "failed to create codec for "
+ + bestCodec, e);
+ }
}
}
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java
index bbba9d8..f5eb513 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java
@@ -28,6 +28,7 @@ import androidx.media.filterfw.FrameImage2D;
import androidx.media.filterfw.ImageShader;
import androidx.media.filterfw.TextureSource;
+import java.io.IOException;
import java.nio.ByteBuffer;
/**
@@ -86,9 +87,16 @@ public class GpuVideoTrackDecoder extends VideoTrackDecoder {
@Override
protected MediaCodec initMediaCodec(MediaFormat format) {
+ MediaCodec mediaCodec;
+ try {
+ mediaCodec = MediaCodec.createDecoderByType(
+ format.getString(MediaFormat.KEY_MIME));
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "failed to create decoder for "
+ + format.getString(MediaFormat.KEY_MIME), e);
+ }
Surface surface = new Surface(mSurfaceTexture);
- MediaCodec mediaCodec = MediaCodec.createDecoderByType(
- format.getString(MediaFormat.KEY_MIME));
mediaCodec.configure(format, surface, null, 0);
surface.release();
return mediaCodec;
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
index 0b85189..8d8d9de 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
@@ -97,7 +97,7 @@ abstract public class CompareActivity extends Activity {
Log.d(LOG_TAG, "failure to access hardware layer");
return;
}
- Method copyInto = hardwareLayer.getClass().getSuperclass()
+ Method copyInto = hardwareLayer.getClass()
.getDeclaredMethod("copyInto", Bitmap.class);
if (!copyInto.isAccessible())
copyInto.setAccessible(true);
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
index a08b558..c90b626 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
@@ -35,23 +35,24 @@ public class ErrorCalculator {
private static final boolean LOG_TIMING = false;
private static final boolean LOG_CALC = false;
- private final RenderScript mRS;
+ private RenderScript mRS;
private Allocation mIdealPixelsAllocation;
private Allocation mGivenPixelsAllocation;
private Allocation mOutputPixelsAllocation;
- private final Allocation mInputRowsAllocation;
- private final Allocation mOutputRegionsAllocation;
+ private Allocation mInputRowsAllocation;
+ private Allocation mOutputRegionsAllocation;
- private final ScriptC_errorCalculator mScript;
+ private ScriptC_errorCalculator mScript;
- private final int[] mOutputRowRegions;
+ private int[] mOutputRowRegions;
public ErrorCalculator(Context c, Resources resources) {
int width = resources.getDimensionPixelSize(R.dimen.layer_width);
int height = resources.getDimensionPixelSize(R.dimen.layer_height);
mOutputRowRegions = new int[height / REGION_SIZE];
+/*
mRS = RenderScript.create(c);
int[] rowIndices = new int[height / REGION_SIZE];
for (int i = 0; i < rowIndices.length; i++)
@@ -67,12 +68,15 @@ public class ErrorCalculator {
mInputRowsAllocation.copyFrom(rowIndices);
mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
+*/
}
private static long startMillis, middleMillis;
public float calcErrorRS(Bitmap ideal, Bitmap given) {
+ if (true)
+ return calcError(ideal, given);
if (LOG_TIMING) {
startMillis = System.currentTimeMillis();
}
diff --git a/tests/DynamicDrawableTest/Android.mk b/tests/DynamicDrawableTest/Android.mk
new file mode 100644
index 0000000..5c51301
--- /dev/null
+++ b/tests/DynamicDrawableTest/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2014 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := DynamicDrawableTest
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/DynamicDrawableTest/AndroidManifest.xml b/tests/DynamicDrawableTest/AndroidManifest.xml
new file mode 100644
index 0000000..4ca3e3c
--- /dev/null
+++ b/tests/DynamicDrawableTest/AndroidManifest.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.test.dynamic" >
+ <uses-sdk android:minSdkVersion="11" />
+
+ <application
+ android:hardwareAccelerated="true"
+ android:label="vector" >
+ <activity
+ android:name="VectorDrawableTest"
+ android:label="Vector Icon" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name="VectorDrawable01"
+ android:label="VectorTest1" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="VectorDrawablePerformance"
+ android:label="Vector Performance" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+
+ <activity
+ android:name="VectorDrawableDupPerf"
+ android:label="Vector Performance of clones" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+ <activity
+ android:name="VectorDrawableStaticPerf"
+ android:label="Performance of vector images" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+
+ <activity
+ android:name="VectorCheckbox"
+ android:label="On a Checkbox" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+ <activity
+ android:name="VectorPathChecking"
+ android:label="Path Checking graphics" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="com.android.test.dynamic.TEST" />
+ </intent-filter>
+
+ </activity>
+ </application>
+
+</manifest> \ No newline at end of file
diff --git a/tests/DynamicDrawableTest/lint.xml b/tests/DynamicDrawableTest/lint.xml
new file mode 100644
index 0000000..ee0eead
--- /dev/null
+++ b/tests/DynamicDrawableTest/lint.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint> \ No newline at end of file
diff --git a/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png b/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..60fbdf5
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/tests/DynamicDrawableTest/res/drawable/icon.png b/tests/DynamicDrawableTest/res/drawable/icon.png
new file mode 100644
index 0000000..cb40a19
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/icon.png
Binary files differ
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml
new file mode 100644
index 0000000..4f4b386
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable01.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:trigger="state_checked" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="480"
+ android:viewportWidth="480" />
+
+ <group>
+ <path
+ android:name="check"
+ android:pathData="m20,200l100,90l180,-180l-35,-35l-145,145l-60,-60l-40,40z"
+ android:fill="#ffff00ff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="5" />
+ </group>
+ <group>
+ <path
+ android:name="box1"
+ android:pathData="m127,171l37,38l33,-31l-37,-40l-1,3l-2,0l-30,30z"
+ android:fill="#ffffffff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="5" />
+ </group>
+ <group>
+ <path
+ android:name="box2"
+ android:pathData="m127,171l37,38l33,-31l-37,-40l-1,3l-2,0l-30,30z"
+ android:fill="#ff000000"
+ android:rotation="46.757"
+ android:pivotX="162"
+ android:pivotY="173.5"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="5" />
+ </group>
+ <group>
+ <path
+ android:name="box3"
+ android:pathData="m187,147l-1,55l-49,-1l2,-53l48,0z"
+ android:stroke="#FF000000"
+ android:strokeWidth="4" />
+ </group>
+ <group>
+ <path
+ android:name="box4"
+ android:pathData="m248,74l0,164l-177,0l1,-165l173,-1l3,2z"
+ android:stroke="#FF000000"
+ android:strokeWidth="30" />
+ </group>
+
+ <animation
+ android:durations="300,100,0,300"
+ android:sequence="check,box1,box2,box3,box4" />
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml
new file mode 100644
index 0000000..49906d17
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable02.xml
@@ -0,0 +1,46 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="320"
+ android:viewportHeight="320"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M 100,225 L 100,115 L 130,115 L 70,15 L 10,115 L 40,115 L 40,225 z"
+ android:fill="#ffffffff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M 130,225 L 130,115 L 130,115 L 70,15 L 10,115 L 10,115 L 10,225 z"
+ android:fill="#ff440000"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="180"
+ android:pivotX="70"
+ android:pivotY="120"
+ android:trimPathStart=".1"
+ android:trimPathEnd=".9"/>
+ </group>
+ <animation android:sequence="arrow,house"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml
new file mode 100644
index 0000000..137049d
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable03.xml
@@ -0,0 +1,137 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="7.30625"
+ android:viewportHeight="12.25"/>
+
+ <group>
+
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 0
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+ <group>
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 0, 0
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 0, 12.25
+ l 7.3, 0
+ l 0, 12.25
+ l -7.3, 0
+ z"
+ android:clipToPath="true"
+ android:rotation="-30"
+ android:pivotX="3.65"
+ android:pivotY="6.125"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+
+
+ <animation
+ android:sequence="one,one"
+ android:durations="4000"/>
+ <animation
+ android:sequence="two,two"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip1,clip1"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip2,clip2"
+ android:durations="4000"/>
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml
new file mode 100644
index 0000000..cffb73f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable04.xml
@@ -0,0 +1,126 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="7.30625"
+ android:viewportHeight="12.25"/>
+
+ <group>
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 3.65, 6.125
+ m -.001, 0
+ a .001,.001 0 1,0 .002,0
+ a .001,.001 0 1,0 -.002,0z"
+ android:clipToPath="true"
+ android:fill="#112233"
+ />
+
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 3.65, 6.125
+ m -6, 0
+ a 6,6 0 1,0 12,0
+ a 6,6 0 1,0 -12,0z"
+ android:clipToPath="true"
+ android:fill="#112233"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+ <group>
+ <path
+ android:name="clip1"
+ android:pathData="
+ M 3.65, 6.125
+ m -6, 0
+ a 6,6 0 1,0 12,0
+ a 6,6 0 1,0 -12,0z"
+ android:clipToPath="true"
+ android:fill="#332233"
+ />
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ff88ff"
+ />
+ <path
+ android:name="clip2"
+ android:pathData="
+ M 3.65, 6.125
+ m -.001, 0
+ a .001,.001 0 1,0 .002,0
+ a .001,.001 0 1,0 -.002,0z"
+ android:clipToPath="true"
+ android:fill="#662233"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ff88ff"
+ />
+ </group>
+
+
+
+ <animation
+ android:sequence="one,one"
+ android:durations="4000"/>
+ <animation
+ android:sequence="two,two"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip1,clip1"
+ android:durations="4000"/>
+ <animation
+ android:sequence="clip2,clip2"
+ android:durations="4000"/>
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml
new file mode 100644
index 0000000..bcf3ae6
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable05.xml
@@ -0,0 +1,147 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="7.30625"
+ android:viewportHeight="12.25"/>
+
+ <group>
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+ l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+ l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ffff00"
+ />
+
+
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ </group>
+ <group>
+ <path
+ android:name="one"
+ android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
+l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+l -5.046875,0.0 0.0,-1.0Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ />
+ </group>
+ <group>
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ />
+ <path
+ android:name="three"
+ android:pathData="M 5.103125,6.003125q 0.84375,0.1875 1.3125,0.765625 0.484375,0.5625 0.484375,1.40625
+ q 0.0,1.296875 -0.890625,2.015625 -0.890625,0.703125 -2.53125,0.703125
+ q -0.546875,0.0 -1.140625,-0.109375 -0.5781251,-0.109375 -1.1875001,-0.328125
+ l 0.0,-1.140625q 0.484375,0.28125 1.0625001,0.4375 0.59375,0.140625 1.234375,0.140625
+ q 1.109375,0.0 1.6875,-0.4375 0.59375,-0.4375 0.59375,-1.28125
+ q 0.0,-0.765625 -0.546875,-1.203125 -0.546875,-0.4375 -1.5,-0.4375
+ l -1.03125,0.0 0.0,-0.96875 1.078125,0.0q 0.859375,0.0 1.328125,-0.34375
+ q 0.46875,-0.359375 0.46875,-1.015625 0.0,-0.671875 -0.484375,-1.03125
+ q -0.46875,-0.359375 -1.359375,-0.359375 -0.5,0.0 -1.0625,0.109375
+ q -0.546875,0.09375 -1.2187501,0.3125l 0.0,-1.046875q 0.6875001,-0.1875 1.2656251,-0.28125
+ q 0.59375,-0.09375 1.109375,-0.09375 1.359375,0.0 2.140625,0.609375
+ q 0.78125,0.609375 0.78125,1.65625 0.0,0.734375 -0.421875,1.234375
+ q -0.40625,0.5 -1.171875,0.6875Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ </group>
+ <group>
+ <path
+ android:name="two"
+ android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
+ q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
+ q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
+ q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
+ q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
+ q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
+ q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
+ q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
+ q -0.78125024,0.8125 -2.2187502,2.265625Z"
+ android:fill="#ffff00"
+ android:fillOpacity="0"
+ />
+ <path
+ android:name="three"
+ android:pathData="M 5.103125,6.003125q 0.84375,0.1875 1.3125,0.765625 0.484375,0.5625 0.484375,1.40625
+ q 0.0,1.296875 -0.890625,2.015625 -0.890625,0.703125 -2.53125,0.703125
+ q -0.546875,0.0 -1.140625,-0.109375 -0.5781251,-0.109375 -1.1875001,-0.328125
+ l 0.0,-1.140625q 0.484375,0.28125 1.0625001,0.4375 0.59375,0.140625 1.234375,0.140625
+ q 1.109375,0.0 1.6875,-0.4375 0.59375,-0.4375 0.59375,-1.28125
+ q 0.0,-0.765625 -0.546875,-1.203125 -0.546875,-0.4375 -1.5,-0.4375
+ l -1.03125,0.0 0.0,-0.96875 1.078125,0.0q 0.859375,0.0 1.328125,-0.34375
+ q 0.46875,-0.359375 0.46875,-1.015625 0.0,-0.671875 -0.484375,-1.03125
+ q -0.46875,-0.359375 -1.359375,-0.359375 -0.5,0.0 -1.0625,0.109375
+ q -0.546875,0.09375 -1.2187501,0.3125l 0.0,-1.046875q 0.6875001,-0.1875 1.2656251,-0.28125
+ q 0.59375,-0.09375 1.109375,-0.09375 1.359375,0.0 2.140625,0.609375
+ q 0.78125,0.609375 0.78125,1.65625 0.0,0.734375 -0.421875,1.234375
+ q -0.40625,0.5 -1.171875,0.6875Z"
+ android:fill="#ffff00"
+ />
+ </group>
+
+
+ <animation
+ android:sequence="one,one,three,three"
+ android:durations="2000,0,2000"/>
+ <animation
+ android:sequence="two,two,two,two"
+ android:durations="2000,0,2000"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml
new file mode 100644
index 0000000..73ff5e2
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable06.xml
@@ -0,0 +1,76 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport
+ android:viewportWidth="700"
+ android:viewportHeight="700"/>
+
+ <group>
+ </group>
+ <path android:pathData="M 569.374 461.472L 569.374 160.658L 160.658 160.658L 160.658 461.472L 569.374 461.472z"
+ android:name="path2451"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.65500000000000"/>
+ <path android:pathData="M 365.015 311.066"
+ android:name="path2453"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 164.46 164.49L 340.78 343.158C 353.849 356.328 377.63 356.172 390.423 343.278L 566.622 165.928"
+ android:name="path2455"
+ android:stroke="#FF000000"
+ android:fill="#FF0000FF"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 170.515 451.566L 305.61 313.46"
+ android:name="path2457"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 557.968 449.974L 426.515 315.375"
+ android:name="path2459"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ <group>
+ <path android:pathData="M 569.374 461.472L 569.374 160.658L 160.658 160.658L 160.658 461.472L 569.374 461.472z"
+ android:name="path2451"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.65500000000000"/>
+ <path android:pathData="M 365.015 311.066"
+ android:name="path2453"
+ android:stroke="#FF000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 164.46 164.49L 340.78 343.158C 353.849 356.328 377.63 356.172 390.423 343.278L 566.622 165.928"
+ android:name="path2455"
+ android:stroke="#FF000000"
+ android:fill="#FFFFFFFF"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 170.515 451.566L 305.61 313.46"
+ android:name="path2457"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ <path android:pathData="M 557.968 449.974L 426.515 315.375"
+ android:name="path2459"
+ android:stroke="#000000"
+ android:strokeWidth="30.655000000000001"/>
+ </group>
+
+ <animation android:sequence="path2451,path2451"
+ android:durations="1000"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml
new file mode 100644
index 0000000..99d37ef
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable07.xml
@@ -0,0 +1,45 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="140"
+ android:viewportHeight="110"/>
+ <group>
+ <path
+ android:name="menu"
+ android:pathData="M 20,20 l 100,0 0,10 -100,0 z
+ M 20,50 l 100,0 0,10 -100,0 z
+ M 20,80 l 0,-10 100,0 0,10 z"
+ android:fill="#ffffffff"/>
+ </group>
+ <group>
+ <path
+ android:name="back"
+ android:pathData="M 20,55 l 35.3,-35.3 7.07,7.07 -35.3,35.3 z
+ M 27,50 l 97,0 0,10 -97,0 z
+ M 20,55 l 7.07,-7.07 35.3,35.3 -7.07,7.07 z"
+ android:fill="#ffffffff"
+ android:rotation="180"
+ android:pivotX="70"
+ android:pivotY="55"
+ />
+ </group>
+ <animation android:sequence="menu,back"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml
new file mode 100644
index 0000000..f8a03d7
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable08.xml
@@ -0,0 +1,48 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="600"
+ android:viewportHeight="600"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M535.441,412.339A280.868,280.868 0 1,1 536.186,161.733L284.493,286.29Z"
+ android:fill="#ffffcc00"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="pie2"
+ android:pathData="M564.441,287A280.868,280.868 0 1,1 564.441,285L284.493,286.29Z"
+ android:fill="#FFccaa00"
+ android:stroke="#FF000000"
+ android:strokeWidth="10"
+ android:pivotX="90"
+ android:pivotY="100"/>
+ </group>
+
+ <animation android:sequence="pie1,pie2"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml
new file mode 100644
index 0000000..09934de
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable09.xml
@@ -0,0 +1,41 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="200"
+ android:viewportHeight="200"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M 20,20 l 60,0 0,140 -60,0 z M 120,20 l 60,0 0,140 -60,0 z"
+ android:fill="#ffffffff"/>
+ </group>
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M 100,20 l 0,0 0,140 -80,0 z M 100,20 l 0,0 80,140 -80,0 z"
+ android:fill="#ffffffff"
+ android:rotation="90"
+ android:pivotX="100"
+ android:pivotY="100"/>
+ </group>
+ <animation android:sequence="arrow,house"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml
new file mode 100644
index 0000000..f17f67a
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable10.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="200"
+ android:viewportWidth="200" />
+
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FF555555" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FF555555" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FF555555" />
+ </group>
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FF555555" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FF555555" />
+ </group>
+
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FF555555" />
+ </group>
+
+ <group>
+ <path
+ android:name="bar3"
+ android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar2"
+ android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar1"
+ android:pathData="M14.001,34.645 L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z"
+ android:fill="#FFFFFFFF" />
+ <path
+ android:name="bar0"
+ android:pathData="M0,20.502l6.999,7.071 c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z"
+ android:fill="#FFFFFFFF" />
+ </group>
+
+ <animation
+ android:sequence="bar0,bar0,bar0,bar0"
+ android:durations="500,500,500"/>
+ <animation
+ android:sequence="bar1,bar1,bar1,bar1"
+ android:durations="500,500,500"/>
+ <animation
+ android:sequence="bar2,bar2,bar2,bar2"
+ android:durations="500,500,500"/>
+ <animation
+ android:sequence="bar3,bar3,bar3,bar3"
+ android:durations="500,500,500"/>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml
new file mode 100644
index 0000000..a1a03be
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable11.xml
@@ -0,0 +1,62 @@
+<!--
+ Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:height="64dp"
+ android:width="64dp" />
+
+ <viewport
+ android:viewportHeight="80"
+ android:viewportWidth="40" />
+
+ <group>
+ <path
+ android:name="battery"
+ android:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"
+ android:fill="#3388ff"
+ android:stroke="#ff8833"
+ android:strokeWidth="1"
+ android:rotation="0"/>
+ <path
+ android:name="spark"
+ android:pathData="M 30,18.031528 L 25.579581,23.421071 L 29.370621,26.765348 L 20.096792,37 L 21.156922,28.014053 L 17,24.902844 L 20.880632,18 L 30,18.031528 z"
+ android:fill="#FFFF0000" />
+
+ </group>
+ <group>
+ <path
+ android:name="battery"
+ android:pathData="M 20.28125,2.0000002 C 17.352748,2.0000002 15,4.3527485 15,7.2812502 L 15,8.0000002 L 13.15625,8.0000002 C 9.7507553,8.0000002 7,10.750759 7,14.15625 L 7,39.84375 C 7,43.24924 9.7507558,46 13.15625,46 L 33.84375,46 C 37.249245,46 39.999999,43.24924 40,39.84375 L 40,14.15625 C 40,10.75076 37.249243,8.0000002 33.84375,8.0000002 L 32,8.0000002 L 32,7.2812502 C 32,4.3527485 29.647252,2.0000002 26.71875,2.0000002 L 20.28125,2.0000002 z"
+ android:fill="#ff8833"
+ android:stroke="#3388ff"
+ android:strokeWidth="1"
+ android:rotation="0" />
+ <path
+ android:name="spark"
+ android:pathData="M 30,18.031528 L 25.579581,23.421071 L 29.370621,26.765348 L 20.096792,37 L 21.156922,28.014053 L 17,24.902844 L 20.880632,18 L 30,18.031528 z"
+ android:fill="#FFFF0000" />
+ </group>
+
+ <animation
+ android:durations="2000"
+ android:sequence="spark,spark" />
+ <animation
+ android:durations="2000"
+ android:sequence="battery,battery" />
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml
new file mode 100644
index 0000000..89748d5
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable12.xml
@@ -0,0 +1,90 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="600"
+ android:viewportHeight="600"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M300,70 a230,230 0 1,0 1,0 z"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="70"
+ android:trimPathStart="0"
+ android:trimPathEnd=".75"
+ android:trimPathOffset="0"/>
+
+ <path
+ android:name="v"
+ android:pathData="M300,70 l 0,-70 70,70 -70,70z"
+ android:fill="#FF00FF00"
+ android:pivotX="300"
+ android:pivotY="300"
+ android:rotation="0"
+ />
+ </group>
+
+ <group>
+ <path
+ android:name="v"
+ android:pathData="M300,70 l 0,-70 70,70 -70,70z"
+ android:pivotX="300"
+ android:pivotY="300"
+ android:rotation="360"/>
+ <path
+ android:name="pie2"
+ android:pathData="M300,70 a230,230 0 1,0 1,0 z"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="70"
+ android:rotation="360"
+ android:pivotX="300"
+ android:pivotY="300"
+ android:trimPathStart="0"
+ android:trimPathEnd=".5"
+ android:trimPathOffset="0"
+ android:strokeLineCap="round"
+ />
+ </group>
+
+ <animation android:sequence="pie1,pie2"
+ android:durations="2000"
+ android:startOffset="500"
+ android:repeatCount="-1"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+ <animation android:sequence="v,v"
+ android:durations="2000"
+ android:startOffset="500"
+ android:repeatCount="-1"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+ <animation android:sequence="pie1,pie2"
+ android:durations="2800"
+ android:startOffset="500"
+ android:limitTo="trimPathEnd"
+ android:repeatCount="-1"
+ android:repeatStyle="reverse"
+ android:animate="easeInOut"
+ />
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml
new file mode 100644
index 0000000..43dda52
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable13.xml
@@ -0,0 +1,82 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+
+ <viewport android:viewportWidth="600"
+ android:viewportHeight="400"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M300,200 h-150 a150,150 0 1,0 150,-150 z"
+ android:fill="#ffffffff"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+
+ <path
+ android:name="half"
+ android:pathData="M275,175 v-150 a150,150 0 0,0 -150,150 z"
+ android:fill="#FFFF0000"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="5"
+ android:rotation="0"
+ android:pivotX="300"
+ android:pivotY="200"/>
+ </group>
+
+ <group>
+ <path
+ android:name="pie2"
+ android:pathData="M300,200 h-150 a150,150 0 1,0 150,-150 z"
+ android:fill="#ffff0000"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="300"
+ android:pivotY="200"/>
+
+ <path
+ android:name="half"
+ android:pathData="M275,175 v-150 a150,150 0 0,0 -150,150 z"
+ android:fill="#FFFFFF00"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="5"
+ android:rotation="-360"
+ android:pivotX="300"
+ android:pivotY="200"/>
+ </group>
+ <animation android:sequence="pie1,pie2"
+ android:durations="1000"
+ android:startOffset="500"
+ android:repeatCount="2"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+ <animation android:sequence="half,half"
+ android:durations="1000"
+ android:startOffset="500"
+ android:repeatCount="5"
+ android:repeatStyle="forward"
+ android:animate="easeInOut"
+ />
+
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml
new file mode 100644
index 0000000..0f1f149
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable14.xml
@@ -0,0 +1,54 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="800"
+ android:viewportHeight="500"/>
+
+ <group>
+ <path
+ android:name="pie1"
+ android:pathData="M200,450 l 50,-25
+ a25,25 -30 0,1 100,-50 l 50,-25
+ a25,50 -30 0,1 100,-50 l 50,-25
+ a25,75 -30 0,1 100,-50 l 50,-25
+ a25,100 -30 0,1 100,-50 l 50,-25"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"/>
+ </group>
+
+ <group>
+ <path
+ android:name="pie2"
+ android:pathData="M200,350 l 50,-25
+ a25,12 -30 0,1 100,-50 l 50,-25
+ a25,25 -30 0,1 100,-50 l 50,-25
+ a25,37 -30 0,1 100,-50 l 50,-25
+ a25,50 -30 0,1 100,-50 l 50,-25"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="20"
+ android:pivotX="90"
+ android:pivotY="100"/>
+
+ </group>
+ <animation android:sequence="pie1,pie2"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml
new file mode 100644
index 0000000..6bc946f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable15.xml
@@ -0,0 +1,48 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="500"
+ android:viewportHeight="400"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:fill="#ffffffff"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:fill="#ff440000"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="10"
+ android:rotation="180"
+ android:pivotX="250"
+ android:pivotY="200"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml
new file mode 100644
index 0000000..c9c8e8a
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable16.xml
@@ -0,0 +1,46 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="200"
+ android:viewportHeight="200"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M 100,10 v 180 M 10,100 h 180"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M 100,10 v 90 M 10,100 h 90"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="100"
+ android:pivotY="100"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml
new file mode 100644
index 0000000..9427652
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable17.xml
@@ -0,0 +1,46 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="1200"
+ android:viewportHeight="600"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M200,300 Q400,50 600,300 T1000,300"
+ android:stroke="#FF00FF00"
+ android:strokeWidth="1"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M200,300 Q400,50 600,300 T1000,300"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="600"
+ android:pivotY="300"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml
new file mode 100644
index 0000000..83dfbd2
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable18.xml
@@ -0,0 +1,45 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="500"
+ android:viewportHeight="400"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:stroke="#FFFFFF00"
+ android:strokeWidth="10"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M100,200 C100,100 250,100 250,200 S400,300 400,200"
+ android:strokeWidth="10"
+ android:rotation="360"
+ android:pivotX="250"
+ android:pivotY="200"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml
new file mode 100644
index 0000000..013254f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable19.xml
@@ -0,0 +1,45 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="1000"
+ android:viewportHeight="800"/>
+
+ <group>
+ <path
+ android:name="arrow"
+ android:pathData="M10,300 Q400,50 600,300 T1000,300"
+ android:stroke="#FF00FFFF"
+ android:strokeWidth="40"/>
+ </group>
+
+ <group>
+ <path
+ android:name="house"
+ android:pathData="M10,300 Q400,550 600,300 T1000,300"
+ android:stroke="#FFFF0000"
+ android:strokeWidth="60"
+ android:pivotX="90"
+ android:pivotY="100"/>
+ </group>
+
+ <animation android:sequence="arrow,house"/>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml b/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml
new file mode 100644
index 0000000..aba7e5f
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_drawable20.xml
@@ -0,0 +1,37 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <size
+ android:width="64dp"
+ android:height="64dp"/>
+
+ <viewport android:viewportWidth="480"
+ android:viewportHeight="480"/>
+
+ <group>
+ <path
+ android:name="edit"
+ android:pathData="M406.667,180c0,0 -100 -100 -113.334 -113.333
+ c-13.333 -13.334 -33.333,0 -33.333,0l-160,160c0,0 -40,153.333 -40,173.333c0,13.333,13.333,13.333,13.333,13.333l173.334 -40
+ c0,0,146.666 -146.666,160 -160C420,200,406.667,180,406.667,180z M226.399,356.823L131.95,378.62l-38.516 -38.522
+ c7.848 -34.675,20.152 -82.52,23.538 -95.593l3.027,2.162l106.667,106.666L226.399,356.823z"
+ android:stroke="#FF000000"
+ android:fill="#FF00FFFF"
+ android:strokeWidth="10"/>
+ </group>
+
+
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml
new file mode 100644
index 0000000..8897181
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_create.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.813995,9.936001l-3.75,-3.75L3.0,17.25zM20.707,7.0429993c0.391,-0.391 0.391,-1.023 0.0,-1.414l-2.336,-2.336c-0.391,-0.391 -1.023,-0.391 -1.414,0.0l-1.832,1.832l3.75,3.75L20.707,7.0429993z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml
new file mode 100644
index 0000000..2c7ebbd
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_delete.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M6.0,19.0c0.0,1.104 0.896,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0,-0.896 2.0,-2.0l0.0,-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0,-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0,-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml
new file mode 100644
index 0000000..e4cf78c
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_heart.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M16.0,5.0c-1.955,0.0 -3.83,1.268 -4.5,3.0c-0.67,-1.732 -2.547,-3.0 -4.5,-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207,-5.242 9.0,-7.971 9.0,-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml
new file mode 100644
index 0000000..cec12ba
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_schedule.xml
@@ -0,0 +1,33 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M11.994999,2.0C6.4679985,2.0 2.0,6.4780006 2.0,12.0s4.468,10.0 9.995,10.0S22.0,17.522 22.0,12.0S17.521,2.0 11.994999,2.0zM12.0,20.0c-4.42,0.0 -8.0,-3.582 -8.0,-8.0s3.58,-8.0 8.0,-8.0s8.0,3.582 8.0,8.0S16.419998,20.0 12.0,20.0z"
+ android:fillOpacity="0.9"
+ />
+<path
+ android:pathData="M12.5,6.0l-1.5,0.0 0.0,7.0 5.3029995,3.1819992 0.75,-1.249999 -4.5529995,-2.7320004z"
+ android:fillOpacity="0.9"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml b/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml
new file mode 100644
index 0000000..5fe1fb6
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_icon_settings.xml
@@ -0,0 +1,29 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="64dp"
+android:height="64dp"/>
+
+ <viewport android:viewportWidth="24"
+ android:viewportHeight="24"/>
+
+<group>
+<path
+ android:pathData="M19.429,12.975998c0.042,-0.32 0.07,-0.645 0.07,-0.976s-0.029,-0.655 -0.07,-0.976l2.113,-1.654c0.188,-0.151 0.243,-0.422 0.118,-0.639l-2.0,-3.463c-0.125,-0.217 -0.386,-0.304 -0.612,-0.218l-2.49,1.004c-0.516,-0.396 -1.081,-0.731 -1.69,-0.984l-0.375,-2.648C14.456,2.1829987 14.25,2.0 14.0,2.0l-4.0,0.0C9.75,2.0 9.544,2.1829987 9.506,2.422001L9.131,5.0699997C8.521,5.322998 7.957,5.6570015 7.44,6.054001L4.952,5.0509987C4.726,4.965 4.464,5.052002 4.34,5.269001l-2.0,3.463C2.2150002,8.947998 2.27,9.219002 2.4580002,9.369999l2.112,1.653C4.528,11.344002 4.5,11.668999 4.5,12.0s0.029,0.656 0.071,0.977L2.4580002,14.630001c-0.188,0.151 -0.243,0.422 -0.118,0.639l2.0,3.463c0.125,0.217 0.386,0.304 0.612,0.218l2.489,-1.004c0.516,0.396 1.081,0.731 1.69,0.984l0.375,2.648C9.544,21.817001 9.75,22.0 10.0,22.0l4.0,0.0c0.25,0.0 0.456,-0.183 0.494,-0.422l0.375,-2.648c0.609,-0.253 1.174,-0.588 1.689,-0.984l2.49,1.004c0.226,0.086 0.487,-0.001 0.612,-0.218l2.0,-3.463c0.125,-0.217 0.07,-0.487 -0.118,-0.639L19.429,12.975998zM12.0,16.0c-2.21,0.0 -4.0,-1.791 -4.0,-4.0c0.0,-2.21 1.79,-4.0 4.0,-4.0c2.208,0.0 4.0,1.79 4.0,4.0C16.0,14.209 14.208,16.0 12.0,16.0z"
+ android:fill="#FF000000"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_test01.xml b/tests/DynamicDrawableTest/res/drawable/vector_test01.xml
new file mode 100644
index 0000000..6beb9d8
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_test01.xml
@@ -0,0 +1,31 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="128dp"
+android:height="128dp"/>
+
+ <viewport android:viewportWidth="512"
+ android:viewportHeight="512"/>
+
+<group>
+<path
+ android:name="002b"
+ android:pathData="M100,200c0,-100 150,-100 150,0s150,100 150,0t-200,299"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="4"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/drawable/vector_test02.xml b/tests/DynamicDrawableTest/res/drawable/vector_test02.xml
new file mode 100644
index 0000000..2c1a28e
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/drawable/vector_test02.xml
@@ -0,0 +1,31 @@
+<!-- Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+<size
+android:width="128dp"
+android:height="128dp"/>
+
+ <viewport android:viewportWidth="512"
+ android:viewportHeight="512"/>
+
+<group>
+<path
+ android:name="002b"
+ android:pathData="M100,200c0,-100 150,-100 150,0s150,100 150,0T-200,299"
+ android:stroke="#FF0000FF"
+ android:strokeWidth="4"
+ />
+</group>
+</vector>
diff --git a/tests/DynamicDrawableTest/res/values/strings.xml b/tests/DynamicDrawableTest/res/values/strings.xml
new file mode 100644
index 0000000..64163c2
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+</resources>
diff --git a/tests/DynamicDrawableTest/res/values/styles.xml b/tests/DynamicDrawableTest/res/values/styles.xml
new file mode 100644
index 0000000..460c0db
--- /dev/null
+++ b/tests/DynamicDrawableTest/res/values/styles.xml
@@ -0,0 +1,16 @@
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+</resources>
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java
new file mode 100644
index 0000000..1060d19
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorCheckbox.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.GridLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorCheckbox extends Activity {
+ private static final String LOGCAT = "VectorDrawable1";
+ int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GridLayout container = new GridLayout(this);
+ container.setColumnCount(5);
+ container.setBackgroundColor(0xFF888888);
+ final Button []bArray = new Button[icon.length];
+
+ for (int i = 0; i < icon.length; i++) {
+ CheckBox checkBox = new CheckBox(this);
+ bArray[i] = checkBox;
+ checkBox.setWidth(200);
+ checkBox.setWidth(200);
+ checkBox.setButtonDrawable(icon[i]);
+ container.addView(checkBox);
+ }
+ setContentView(container);
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java
new file mode 100644
index 0000000..0ae4b6d
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawable01.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawable01 extends Activity implements View.OnClickListener {
+ private static final String LOGCAT = "VectorDrawable1";
+ int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GridLayout container = new GridLayout(this);
+ container.setColumnCount(5);
+ container.setBackgroundColor(0xFF888888);
+ final Button []bArray = new Button[icon.length];
+
+ for (int i = 0; i < icon.length; i++) {
+ Button button = new Button(this);
+ bArray[i] = button;
+ button.setWidth(200);
+ button.setWidth(200);
+ button.setBackgroundResource(icon[i]);
+ container.addView(button);
+ button.setOnClickListener(this);
+ }
+ Button b = new Button(this);
+ b.setText("Run All");
+ b.setOnClickListener(new View.OnClickListener(){
+
+ @Override
+ public void onClick(View v) {
+ for (int i = 0; i < bArray.length; i++) {
+ VectorDrawable d = (VectorDrawable) bArray[i].getBackground();
+ d.start();
+ }
+ }});
+ container.addView(b);
+ setContentView(container);
+
+ }
+
+ @Override
+ public void onClick(View v) {
+ VectorDrawable d = (VectorDrawable) v.getBackground();
+ d.start();
+ }
+
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java
new file mode 100644
index 0000000..a00bc5e
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableDupPerf.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawableDupPerf extends VectorDrawablePerformance {
+ {
+ icon = new int[]{
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable04,
+ };
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
new file mode 100644
index 0000000..9e8ea75
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.GridLayout;
+import android.widget.ScrollView;
+import java.text.DecimalFormat;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawablePerformance extends Activity implements View.OnClickListener {
+ private static final String LOGCAT = "VectorDrawable1";
+ protected int[] icon = {
+ R.drawable.vector_drawable01,
+ R.drawable.vector_drawable02,
+ R.drawable.vector_drawable03,
+ R.drawable.vector_drawable04,
+ R.drawable.vector_drawable05,
+ R.drawable.vector_drawable06,
+ R.drawable.vector_drawable07,
+ R.drawable.vector_drawable08,
+ R.drawable.vector_drawable09,
+ R.drawable.vector_drawable10,
+ R.drawable.vector_drawable11,
+ R.drawable.vector_drawable12,
+ R.drawable.vector_drawable13,
+ R.drawable.vector_drawable14,
+ R.drawable.vector_drawable15,
+ R.drawable.vector_drawable16,
+ R.drawable.vector_drawable17,
+ R.drawable.vector_drawable18,
+ R.drawable.vector_drawable19,
+ R.drawable.vector_drawable20
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ScrollView scrollView = new ScrollView(this);
+ GridLayout container = new GridLayout(this);
+ scrollView.addView(container);
+ container.setColumnCount(5);
+ Resources res = this.getResources();
+ container.setBackgroundColor(0xFF888888);
+ VectorDrawable []d = new VectorDrawable[icon.length];
+ long time = android.os.SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < icon.length; i++) {
+ d[i] = VectorDrawable.create(res,icon[i]);
+ }
+ time = android.os.SystemClock.elapsedRealtimeNanos()-time;
+ TextView t = new TextView(this);
+ DecimalFormat df = new DecimalFormat("#.##");
+ t.setText("avgL=" + df.format(time / (icon.length * 1000000.)) + " ms");
+ t.setBackgroundColor(0xFF000000);
+ container.addView(t);
+ time = android.os.SystemClock.elapsedRealtimeNanos();
+ for (int i = 0; i < icon.length; i++) {
+ Button button = new Button(this);
+ button.setWidth(200);
+ button.setWidth(200);
+ button.setBackgroundResource(icon[i]);
+ container.addView(button);
+ button.setOnClickListener(this);
+ }
+ setContentView(scrollView);
+ time = android.os.SystemClock.elapsedRealtimeNanos()-time;
+ t = new TextView(this);
+ t.setText("avgS=" + df.format(time / (icon.length * 1000000.)) + " ms");
+ t.setBackgroundColor(0xFF000000);
+ container.addView(t);
+ }
+
+ @Override
+ public void onClick(View v) {
+ VectorDrawable d = (VectorDrawable) v.getBackground();
+ d.start();
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java
new file mode 100644
index 0000000..9d3eded
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableStaticPerf.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+import android.app.Activity;
+import android.content.res.Resources;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorDrawableStaticPerf extends VectorDrawablePerformance {
+ {
+ icon = new int[]{
+ R.drawable.vector_icon_create,
+ R.drawable.vector_icon_delete,
+ R.drawable.vector_icon_heart,
+ R.drawable.vector_icon_schedule,
+ R.drawable.vector_icon_settings,
+ };
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java
new file mode 100644
index 0000000..704d3d7
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorDrawableTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.dynamic;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@SuppressWarnings("UnusedDeclaration")
+public class VectorDrawableTest extends android.app.ListActivity {
+ private static final String EXTRA_PATH = "com.android.test.dynamic.Path";
+ private static final String CATEGORY_HWUI_TEST = "com.android.test.dynamic.TEST";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
+ String path = intent.getStringExtra("com.android.test.hwui.Path");
+
+ if (path == null) {
+ path = "";
+ }
+
+ setListAdapter(new SimpleAdapter(this, getData(path),
+ android.R.layout.simple_list_item_1, new String[] { "title" },
+ new int[] { android.R.id.text1 }));
+ getListView().setTextFilterEnabled(true);
+ }
+
+ protected List<Map<String, Object>> getData(String prefix) {
+ List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
+
+ Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(CATEGORY_HWUI_TEST);
+
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
+
+ if (null == list)
+ return myData;
+
+ String[] prefixPath;
+ String prefixWithSlash = prefix;
+
+ if (prefix.equals("")) {
+ prefixPath = null;
+ } else {
+ prefixPath = prefix.split("/");
+ prefixWithSlash = prefix + "/";
+ }
+
+ int len = list.size();
+
+ Map<String, Boolean> entries = new HashMap<String, Boolean>();
+
+ for (int i = 0; i < len; i++) {
+ ResolveInfo info = list.get(i);
+ CharSequence labelSeq = info.loadLabel(pm);
+ String label = labelSeq != null
+ ? labelSeq.toString()
+ : info.activityInfo.name;
+
+ if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
+
+ String[] labelPath = label.split("/");
+
+ String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
+
+ if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
+ addItem(myData, nextLabel, activityIntent(
+ info.activityInfo.applicationInfo.packageName,
+ info.activityInfo.name));
+ } else {
+ if (entries.get(nextLabel) == null) {
+ addItem(myData, nextLabel, browseIntent(prefix.equals("") ?
+ nextLabel : prefix + "/" + nextLabel));
+ entries.put(nextLabel, true);
+ }
+ }
+ }
+ }
+
+ Collections.sort(myData, sDisplayNameComparator);
+
+ return myData;
+ }
+
+ private final static Comparator<Map<String, Object>> sDisplayNameComparator =
+ new Comparator<Map<String, Object>>() {
+ private final Collator collator = Collator.getInstance();
+
+ public int compare(Map<String, Object> map1, Map<String, Object> map2) {
+ return collator.compare(map1.get("title"), map2.get("title"));
+ }
+ };
+
+ protected Intent activityIntent(String pkg, String componentName) {
+ Intent result = new Intent();
+ result.setClassName(pkg, componentName);
+ return result;
+ }
+
+ protected Intent browseIntent(String path) {
+ Intent result = new Intent();
+ result.setClass(this, VectorDrawableTest.class);
+ result.putExtra(EXTRA_PATH, path);
+ return result;
+ }
+
+ protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
+ Map<String, Object> temp = new HashMap<String, Object>();
+ temp.put("title", name);
+ temp.put("intent", intent);
+ data.add(temp);
+ }
+
+ @Override
+ @SuppressWarnings({ "unchecked", "UnusedParameters" })
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
+
+ Intent intent = (Intent) map.get("intent");
+ startActivity(intent);
+ }
+}
diff --git a/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java
new file mode 100644
index 0000000..3430192
--- /dev/null
+++ b/tests/DynamicDrawableTest/src/com/android/test/dynamic/VectorPathChecking.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.test.dynamic;
+
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class VectorPathChecking extends VectorDrawablePerformance {
+ {
+ icon = new int[]{
+ R.drawable.vector_test01,
+ R.drawable.vector_test02
+ };
+ }
+}
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
index 4d3a843..196a5c1 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
@@ -24,7 +24,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
-import static android.view.Gravity.*;
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.CENTER;
+import static android.view.Gravity.FILL;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.NO_GRAVITY;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
public abstract class AbstractLayoutTest extends Activity {
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
index b1c4486..5559707 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
@@ -20,15 +20,25 @@ import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridLayout;
+import android.widget.GridLayout.Alignment;
+import android.widget.GridLayout.LayoutParams;
import android.widget.TextView;
-import static android.widget.GridLayout.*;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.BOTTOM;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.TOP;
+import static android.widget.GridLayout.spec;
-public class AlignmentTest extends Activity {
+public class AlignmentTest extends Activity {
public static final String[] HORIZONTAL_NAMES = {"LEFT", "center", "east", "fill"};
public static final Alignment[] HORIZONTAL_ALIGNMENTS = {LEFT, CENTER, RIGHT, FILL};
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
index 4ce449a..8047c5f 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
@@ -21,7 +21,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
-import static android.widget.GridLayout.*;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.UNDEFINED;
+import static android.widget.GridLayout.VERTICAL;
+import static android.widget.GridLayout.spec;
public class GridLayoutTest extends AbstractLayoutTest {
public ViewGroup create(Context context) {
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
index c7f4665..dc5b12c 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
@@ -20,9 +20,9 @@ import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
-import static android.widget.LinearLayout.*;
-import static android.widget.LinearLayout.LayoutParams.*;
+import static android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
public class LinearLayoutTest extends AbstractLayoutTest {
public ViewGroup create(Context context) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 1bb0db0..c8eefe0 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -706,6 +706,15 @@
</activity>
<activity
+ android:name="ColorFiltersMutateActivity"
+ android:label="ColorFilters/Mutate Filters">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.hwui.TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="LinesActivity"
android:label="Draw/Lines">
<intent-filter>
@@ -849,5 +858,23 @@
</intent-filter>
</activity>
+ <activity
+ android:name="ProjectionActivity"
+ android:label="Reordering/Projection">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.hwui.TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="IsolationVolumeActivity"
+ android:label="Reordering/IsolationVolume">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.android.test.hwui.TEST" />
+ </intent-filter>
+ </activity>
+
</application>
</manifest>
diff --git a/tests/HwAccelerationTest/res/layout/isolation.xml b/tests/HwAccelerationTest/res/layout/isolation.xml
new file mode 100644
index 0000000..e66db19
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/isolation.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#f55">
+ <!-- Left and right layouts are not isolated volumes, so the text views
+ will interleave since they share an isolated z volume-->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="200dp"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView style="@style/TopLeftReorderTextView"/>
+ <TextView style="@style/BottomLeftReorderTextView"/>
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="200dp"
+ android:layout_weight="1"
+ android:translationY="50dp"
+ android:orientation="vertical">
+ <TextView style="@style/TopRightReorderTextView"/>
+ <TextView style="@style/BottomRightReorderTextView"/>
+ </LinearLayout>
+ </LinearLayout>
+
+ <!-- Left and right volumes are isolated by default, so no interleaving will be seen. -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="200dp"
+ android:layout_weight="1"
+ android:orientation="vertical">
+ <TextView style="@style/TopLeftReorderTextView"/>
+ <TextView style="@style/BottomLeftReorderTextView"/>
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="200dp"
+ android:layout_weight="1"
+ android:translationY="50dp"
+ android:orientation="vertical">
+ <TextView style="@style/TopRightReorderTextView"/>
+ <TextView style="@style/BottomRightReorderTextView"/>
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/layout/projection.xml b/tests/HwAccelerationTest/res/layout/projection.xml
new file mode 100644
index 0000000..b6e4c5e
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/projection.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="#66ff0000"
+ tools:context="com.example.projection.ProjectionActivity"
+ tools:ignore="MergeRootFrame">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ android:textSize="50sp"
+ android:text="TextView"/>
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ android:clipChildren="false">
+ <view class="com.android.test.hwui.ProjectionActivity$ProjectedView"
+ android:id="@+id/projection"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:textSize="50sp"
+ android:text="TextView"/>
+ </FrameLayout>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ android:textSize="50sp"
+ android:text="TextView"/>
+</LinearLayout> \ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/values/styles.xml b/tests/HwAccelerationTest/res/values/styles.xml
new file mode 100644
index 0000000..cde5d20
--- /dev/null
+++ b/tests/HwAccelerationTest/res/values/styles.xml
@@ -0,0 +1,34 @@
+<resources>
+ <style name="ReorderTextView" parent="@android:style/TextAppearance.Medium">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">100dp</item>
+ <item name="android:gravity">center</item>
+ </style>
+ <style name="LeftReorderTextView" parent="@style/ReorderTextView">
+ <item name="android:translationX">20dp</item>
+ </style>
+ <style name="RightReorderTextView" parent="@style/ReorderTextView">
+ <item name="android:translationX">-20dp</item>
+ </style>
+
+ <style name="TopLeftReorderTextView" parent="@style/LeftReorderTextView">
+ <item name="android:background">#666</item>
+ <item name="android:text">100</item>
+ <item name="android:translationZ">100dp</item>
+ </style>
+ <style name="BottomLeftReorderTextView" parent="@style/LeftReorderTextView">
+ <item name="android:background">#bbb</item>
+ <item name="android:text">300</item>
+ <item name="android:translationZ">300dp</item>
+ </style>
+ <style name="TopRightReorderTextView" parent="@style/RightReorderTextView">
+ <item name="android:background">#888</item>
+ <item name="android:text">200</item>
+ <item name="android:translationZ">200dp</item>
+ </style>
+ <style name="BottomRightReorderTextView" parent="@style/RightReorderTextView">
+ <item name="android:background">#ccc</item>
+ <item name="android:text">400</item>
+ <item name="android:translationZ">400dp</item>
+ </style>
+</resources>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
new file mode 100644
index 0000000..808b5d3
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.LightingColorFilter;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ColorFiltersMutateActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final BitmapsView view = new BitmapsView(this);
+ setContentView(view);
+ }
+
+ static class BitmapsView extends View {
+ private final Bitmap mBitmap1;
+ private final Bitmap mBitmap2;
+ private final Paint mColorMatrixPaint;
+ private final Paint mLightingPaint;
+ private final Paint mBlendPaint;
+
+ private float mSaturation = 0.0f;
+ private int mLightAdd = 0;
+ private int mLightMul = 0;
+ private int mPorterDuffColor = 0;
+
+ BitmapsView(Context c) {
+ super(c);
+
+ mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
+ mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset2);
+
+ mColorMatrixPaint = new Paint();
+ final ColorMatrix colorMatrix = new ColorMatrix();
+ colorMatrix.setSaturation(0);
+ mColorMatrixPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
+
+ mLightingPaint = new Paint();
+ mLightingPaint.setColorFilter(new LightingColorFilter(0, 0));
+
+ mBlendPaint = new Paint();
+ mBlendPaint.setColorFilter(new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_OVER));
+
+ ObjectAnimator sat = ObjectAnimator.ofFloat(this, "saturation", 1.0f);
+ sat.setDuration(1000);
+ sat.setRepeatCount(ObjectAnimator.INFINITE);
+ sat.setRepeatMode(ObjectAnimator.REVERSE);
+ sat.start();
+
+ ObjectAnimator light = ObjectAnimator.ofInt(this, "lightAdd", 0x00101030);
+ light.setEvaluator(new ArgbEvaluator());
+ light.setDuration(1000);
+ light.setRepeatCount(ObjectAnimator.INFINITE);
+ light.setRepeatMode(ObjectAnimator.REVERSE);
+ light.start();
+
+ ObjectAnimator mult = ObjectAnimator.ofInt(this, "lightMul", 0x0060ffff);
+ mult.setEvaluator(new ArgbEvaluator());
+ mult.setDuration(1000);
+ mult.setRepeatCount(ObjectAnimator.INFINITE);
+ mult.setRepeatMode(ObjectAnimator.REVERSE);
+ mult.start();
+
+ ObjectAnimator color = ObjectAnimator.ofInt(this, "porterDuffColor", 0x7f990040);
+ color.setEvaluator(new ArgbEvaluator());
+ color.setDuration(1000);
+ color.setRepeatCount(ObjectAnimator.INFINITE);
+ color.setRepeatMode(ObjectAnimator.REVERSE);
+ color.start();
+ }
+
+ public int getPorterDuffColor() {
+ return mPorterDuffColor;
+ }
+
+ public void setPorterDuffColor(int porterDuffColor) {
+ mPorterDuffColor = porterDuffColor;
+ final PorterDuffColorFilter filter =
+ (PorterDuffColorFilter) mBlendPaint.getColorFilter();
+ filter.setColor(mPorterDuffColor);
+ invalidate();
+ }
+
+ public int getLightAdd() {
+ return mLightAdd;
+ }
+
+ public void setLightAdd(int lightAdd) {
+ mLightAdd = lightAdd;
+ final LightingColorFilter filter =
+ (LightingColorFilter) mLightingPaint.getColorFilter();
+ filter.setColorAdd(lightAdd);
+ invalidate();
+ }
+
+ public int getLightMul() {
+ return mLightAdd;
+ }
+
+ public void setLightMul(int lightMul) {
+ mLightMul = lightMul;
+ final LightingColorFilter filter =
+ (LightingColorFilter) mLightingPaint.getColorFilter();
+ filter.setColorMultiply(lightMul);
+ invalidate();
+ }
+
+ public void setSaturation(float saturation) {
+ mSaturation = saturation;
+ final ColorMatrixColorFilter filter =
+ (ColorMatrixColorFilter) mColorMatrixPaint.getColorFilter();
+ final ColorMatrix m = filter.getColorMatrix();
+ m.setSaturation(saturation);
+ filter.setColorMatrix(m);
+ invalidate();
+ }
+
+ public float getSaturation() {
+ return mSaturation;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.drawARGB(255, 255, 255, 255);
+
+ canvas.save();
+ canvas.translate(120.0f, 50.0f);
+ canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mColorMatrixPaint);
+
+ canvas.translate(0.0f, 50.0f + mBitmap1.getHeight());
+ canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mLightingPaint);
+
+ canvas.translate(0.0f, 50.0f + mBitmap1.getHeight());
+ canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mBlendPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(120.0f + mBitmap1.getWidth() + 120.0f, 50.0f);
+ canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mColorMatrixPaint);
+
+ canvas.translate(0.0f, 50.0f + mBitmap2.getHeight());
+ canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mLightingPaint);
+
+ canvas.translate(0.0f, 50.0f + mBitmap2.getHeight());
+ canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mBlendPaint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java
new file mode 100644
index 0000000..d5c93f2
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java
@@ -0,0 +1,12 @@
+package com.android.test.hwui;
+
+import android.os.Bundle;
+import android.app.Activity;
+
+public class IsolationVolumeActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.isolation);
+ }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
new file mode 100644
index 0000000..5ba3ad9
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
@@ -0,0 +1,83 @@
+package com.android.test.hwui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Bundle;
+
+import android.app.Activity;
+import android.util.AttributeSet;
+import android.view.RenderNode;
+import android.view.View;
+import android.widget.LinearLayout;
+
+public class ProjectionActivity extends Activity {
+ /**
+ * The content from this view should be projected in between the background of the
+ * ProjecteeLayout and its children, unclipped.
+ *
+ * This view doesn't clip to its bounds (because its parent has clipChildren=false) so that
+ * when it is projected onto the ProjecteeLayout, it draws outside its view bounds.
+ */
+ public static class ProjectedView extends View {
+ private final Paint mPaint = new Paint();
+ private final RectF mRectF = new RectF();
+
+ public ProjectedView(Context context) {
+ this(context, null);
+ }
+
+ public ProjectedView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ProjectedView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ setOnClickListener(new OnClickListener() {
+ boolean toggle = false;
+ @Override
+ public void onClick(View v) {
+ toggle = !toggle;
+ setProject(toggle);
+ }
+ });
+ }
+
+ private void setProject(boolean value) {
+ RenderNode displayList = getDisplayList();
+ if (displayList != null) {
+ displayList.setProjectBackwards(value);
+ }
+ // NOTE: we can't invalidate ProjectedView for the redraw because:
+ // 1) the view won't preserve displayList properties that it doesn't know about
+ // 2) the damage rect won't be big enough
+
+ // instead, twiddle properties on the container, so that enough area of the screen is
+ // redrawn without rerecording any DisplayLists.
+ container.setTranslationX(100f);
+ container.setTranslationX(0.0f);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ // TODO: set projection flag
+ final int w = getWidth();
+ final int h = getHeight();
+ mRectF.set(0, -h, w, 2 * h);
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(0x5f00ff00);
+ canvas.drawOval(mRectF, mPaint);
+ }
+ }
+
+ static View container;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.projection);
+ container = findViewById(R.id.container);
+ }
+}
diff --git a/tests/IdleServiceTest/Android.mk b/tests/IdleServiceTest/Android.mk
new file mode 100644
index 0000000..a7879c5
--- /dev/null
+++ b/tests/IdleServiceTest/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := IdleServiceTest
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/tests/IdleServiceTest/AndroidManifest.xml b/tests/IdleServiceTest/AndroidManifest.xml
new file mode 100644
index 0000000..16d2324
--- /dev/null
+++ b/tests/IdleServiceTest/AndroidManifest.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.idleservicetest">
+
+ <application>
+ <service android:name="TestService"
+ android:exported="true"
+ android:enabled="true"
+ android:permission="android.permission.BIND_IDLE_SERVICE" >
+ <intent-filter>
+ <action android:name="android.service.idle.IdleService" />
+ </intent-filter>
+ </service>
+
+ <service android:name="CrashingTestService"
+ android:exported="true"
+ android:enabled="true"
+ android:permission="android.permission.BIND_IDLE_SERVICE" >
+ <intent-filter>
+ <action android:name="android.service.idle.IdleService" />
+ </intent-filter>
+ </service>
+
+ <service android:name="TimeoutTestService"
+ android:exported="true"
+ android:enabled="true"
+ android:permission="android.permission.BIND_IDLE_SERVICE" >
+ <intent-filter>
+ <action android:name="android.service.idle.IdleService" />
+ </intent-filter>
+ </service>
+
+ <!-- UnpermissionedTestService should never run because it does
+ not require the necessary permission in its <service> block -->
+ <service android:name="UnpermissionedTestService"
+ android:exported="true"
+ android:enabled="true" >
+ <intent-filter>
+ <action android:name="android.service.idle.IdleService" />
+ </intent-filter>
+ </service>
+
+ </application>
+</manifest>
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java
new file mode 100644
index 0000000..022ebcf
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.os.Handler;
+import android.util.Log;
+
+public class CrashingTestService extends IdleService {
+ static final String TAG = "CrashingTestService";
+
+ String mNull = null;
+
+ @Override
+ public boolean onIdleStart() {
+ Log.i(TAG, "Idle maintenance: onIdleStart()");
+
+ Handler h = new Handler();
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ Log.i(TAG, "Explicitly crashing");
+ if (mNull.equals("")) {
+ Log.i(TAG, "won't happen");
+ }
+ }
+ };
+ Log.i(TAG, "Posting explicit crash in 15 seconds");
+ h.postDelayed(r, 15 * 1000);
+ return true;
+ }
+
+ @Override
+ public void onIdleStop() {
+ Log.i(TAG, "Idle maintenance: onIdleStop()");
+ }
+
+}
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java
new file mode 100644
index 0000000..7e9805f
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.os.Handler;
+import android.util.Log;
+
+public class TestService extends IdleService {
+ static final String TAG = "TestService";
+
+ @Override
+ public boolean onIdleStart() {
+ Log.i(TAG, "Idle maintenance: onIdleStart()");
+
+ Handler h = new Handler();
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ Log.i(TAG, "Explicitly finishing idle");
+ finishIdle();
+ }
+ };
+ Log.i(TAG, "Posting explicit finish in 15 seconds");
+ h.postDelayed(r, 15 * 1000);
+ return true;
+ }
+
+ @Override
+ public void onIdleStop() {
+ Log.i(TAG, "Idle maintenance: onIdleStop()");
+ }
+
+}
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java
new file mode 100644
index 0000000..b2ba21b
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.util.Log;
+
+public class TimeoutTestService extends IdleService {
+ private static final String TAG = "TimeoutTestService";
+
+ @Override
+ public boolean onIdleStart() {
+ Log.i(TAG, "onIdleStart() but anticipating time-slice timeout");
+ return true;
+ }
+
+ @Override
+ public void onIdleStop() {
+ Log.i(TAG, "onIdleStop() so we're done");
+ }
+
+}
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java
new file mode 100644
index 0000000..b9fe32b
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.util.Log;
+
+// Should never be invoked because its manifest declaration does not
+// require the necessary permission.
+public class UnpermissionedTestService extends IdleService {
+ private static final String TAG = "UnpermissionedTestService";
+
+ @Override
+ public boolean onIdleStart() {
+ Log.e(TAG, "onIdleStart() for this service should never be called!");
+ return false;
+ }
+
+ @Override
+ public void onIdleStop() {
+ Log.e(TAG, "onIdleStop() for this service should never be called!");
+ }
+
+}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
index 25ac2f0..299e6bb 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
@@ -81,11 +81,11 @@ public class InputTypeActivity extends Activity {
/* Uri Edit Text */
mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_URI,
- R.string.uri_edit_text_label));
+ R.string.uri_edit_text_label));
/* Email Address Edit Text */
mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS,
- R.string.email_address_edit_text_label));
+ R.string.email_address_edit_text_label));
/* Email Subject Text */
mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT,
@@ -142,7 +142,7 @@ public class InputTypeActivity extends Activity {
private View buildEntryView(int inputType, int label) {
- View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
+ View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
EditText editText = (EditText) view.findViewById(R.id.data);
editText.setInputType(inputType);
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
index a1c5fd2..2db11c5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
@@ -24,26 +24,26 @@ import com.android.imftest.R;
public class BigEditTextActivityNonScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityNonScrollablePanScan> {
- public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
-
+ public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
+
public BigEditTextActivityNonScrollablePanScanTests() {
super(BigEditTextActivityNonScrollablePanScan.class);
}
-
- @LargeTest
- public void testAppAdjustmentPanScan() {
- // Give the IME 2 seconds to appear.
- pause(2000);
+
+ @LargeTest
+ public void testAppAdjustmentPanScan() {
+ // Give the IME 2 seconds to appear.
+ pause(2000);
+
+ View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
+ View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
+
+ assertNotNull(rootView);
+ assertNotNull(servedView);
+
+ destructiveCheckImeInitialState(rootView, servedView);
- View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
- View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
-
- assertNotNull(rootView);
- assertNotNull(servedView);
-
- destructiveCheckImeInitialState(rootView, servedView);
-
verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
- }
-
+ }
+
}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
index 2e0b0eb..1050794 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
@@ -24,14 +24,14 @@ import com.android.imftest.R;
public class BigEditTextActivityNonScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityNonScrollableResize> {
- public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
-
+ public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
+
public BigEditTextActivityNonScrollableResizeTests() {
super(BigEditTextActivityNonScrollableResize.class);
}
-
- @LargeTest
- public void testAppAdjustmentPanScan() { // Give the IME 2 seconds to appear.
+
+ @LargeTest
+ public void testAppAdjustmentPanScan() { // Give the IME 2 seconds to appear.
pause(2000);
View rootView = ((BigEditTextActivityNonScrollableResize) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@ public class BigEditTextActivityNonScrollableResizeTests extends ImfBaseTestCase
destructiveCheckImeInitialState(rootView, servedView);
verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
- }
-
+ }
+
}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
index d3eefb5..1e848b0 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
@@ -24,14 +24,14 @@ import com.android.imftest.R;
public class BigEditTextActivityScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityScrollablePanScan> {
- public final String TAG = "BigEditTextActivityScrollablePanScanTests";
-
+ public final String TAG = "BigEditTextActivityScrollablePanScanTests";
+
public BigEditTextActivityScrollablePanScanTests() {
super(BigEditTextActivityScrollablePanScan.class);
}
-
- @LargeTest
- public void testAppAdjustmentPanScan() { // Give the IME 2 seconds to appear.
+
+ @LargeTest
+ public void testAppAdjustmentPanScan() { // Give the IME 2 seconds to appear.
pause(2000);
View rootView = ((BigEditTextActivityScrollablePanScan) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@ public class BigEditTextActivityScrollablePanScanTests extends ImfBaseTestCase<B
destructiveCheckImeInitialState(rootView, servedView);
verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
- }
-
+ }
+
}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
index 5c40e6d..de607d6 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
@@ -24,15 +24,15 @@ import com.android.imftest.R;
public class BigEditTextActivityScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityScrollableResize> {
- public final String TAG = "BigEditTextActivityScrollableResizeTests";
-
+ public final String TAG = "BigEditTextActivityScrollableResizeTests";
+
public BigEditTextActivityScrollableResizeTests() {
super(BigEditTextActivityScrollableResize.class);
}
-
- @LargeTest
- public void testAppAdjustmentPanScan() {
- // Give the IME 2 seconds to appear.
+
+ @LargeTest
+ public void testAppAdjustmentPanScan() {
+ // Give the IME 2 seconds to appear.
pause(2000);
View rootView = ((BigEditTextActivityScrollableResize) mTargetActivity).getRootView();
@@ -44,6 +44,6 @@ public class BigEditTextActivityScrollableResizeTests extends ImfBaseTestCase<Bi
destructiveCheckImeInitialState(rootView, servedView);
verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
- }
-
+ }
+
}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
index 9a93133..c521905 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
@@ -24,14 +24,14 @@ import com.android.imftest.R;
public class BottomEditTextActivityPanScanTests extends ImfBaseTestCase<BottomEditTextActivityPanScan> {
- public final String TAG = "BottomEditTextActivityPanScanTests";
-
+ public final String TAG = "BottomEditTextActivityPanScanTests";
+
public BottomEditTextActivityPanScanTests() {
super(BottomEditTextActivityPanScan.class);
}
-
- @LargeTest
- public void testAppAdjustmentPanScan() {
+
+ @LargeTest
+ public void testAppAdjustmentPanScan() {
// Give the IME 2 seconds to appear.
pause(2000);
@@ -44,6 +44,6 @@ public class BottomEditTextActivityPanScanTests extends ImfBaseTestCase<BottomEd
destructiveCheckImeInitialState(rootView, servedView);
verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
- }
-
+ }
+
}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
index ae900c3..f6f97b5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
@@ -23,8 +23,8 @@ import android.widget.Button;
public class ButtonActivityTest extends ImfBaseTestCase<ButtonActivity> {
- final public String TAG = "ButtonActivityTest";
-
+ final public String TAG = "ButtonActivityTest";
+
public ButtonActivityTest() {
super(ButtonActivity.class);
}
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
index ed5b0c9..6147d3c 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
@@ -22,21 +22,21 @@ import android.view.View;
public class OneEditTextActivityNotSelectedTests extends ImfBaseTestCase<OneEditTextActivityNotSelected> {
- public final String TAG = "OneEditTextActivityNotSelectedTests";
-
+ public final String TAG = "OneEditTextActivityNotSelectedTests";
+
public OneEditTextActivityNotSelectedTests() {
super(OneEditTextActivityNotSelected.class);
}
- @LargeTest
- public void testSoftKeyboardNoAutoPop() {
-
- // Give the IME 2 seconds to appear.
- pause(2000);
-
- assertFalse(mImm.isAcceptingText());
-
- View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
+ @LargeTest
+ public void testSoftKeyboardNoAutoPop() {
+
+ // Give the IME 2 seconds to appear.
+ pause(2000);
+
+ assertFalse(mImm.isAcceptingText());
+
+ View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
View servedView = ((OneEditTextActivityNotSelected) mTargetActivity).getDefaultFocusedView();
assertNotNull(rootView);
@@ -45,6 +45,6 @@ public class OneEditTextActivityNotSelectedTests extends ImfBaseTestCase<OneEdit
destructiveCheckImeInitialState(rootView, servedView);
verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
- }
-
+ }
+
}
diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk
new file mode 100644
index 0000000..93b9c9a
--- /dev/null
+++ b/tests/OneMedia/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+ $(call all-Iaidl-files-under, src)
+
+LOCAL_PACKAGE_NAME := OneMedia
+LOCAL_CERTIFICATE := platform
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-v7-appcompat \
+ android-support-v7-mediarouter
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
new file mode 100644
index 0000000..7d6ba1d
--- /dev/null
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.onemedia"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="19"/>
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.android.onemedia.OnePlayerActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <service
+ android:name="com.android.onemedia.OnePlayerService"
+ android:exported="false"
+ android:process="com.android.onemedia.service" />
+ </application>
+
+</manifest>
diff --git a/tests/OneMedia/res/drawable-hdpi/ic_launcher.png b/tests/OneMedia/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..288b665
--- /dev/null
+++ b/tests/OneMedia/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/drawable-mdpi/ic_launcher.png b/tests/OneMedia/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6ae570b
--- /dev/null
+++ b/tests/OneMedia/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/drawable-xhdpi/ic_launcher.png b/tests/OneMedia/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d4fb7cd
--- /dev/null
+++ b/tests/OneMedia/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/drawable-xxhdpi/ic_launcher.png b/tests/OneMedia/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..85a6081
--- /dev/null
+++ b/tests/OneMedia/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/layout/activity_main.xml b/tests/OneMedia/res/layout/activity_main.xml
new file mode 100644
index 0000000..168c9b8
--- /dev/null
+++ b/tests/OneMedia/res/layout/activity_main.xml
@@ -0,0 +1,16 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/hello_world" />
+
+</RelativeLayout>
diff --git a/tests/OneMedia/res/layout/activity_one_player.xml b/tests/OneMedia/res/layout/activity_one_player.xml
new file mode 100644
index 0000000..4208355
--- /dev/null
+++ b/tests/OneMedia/res/layout/activity_one_player.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2014 Google Inc. All Rights Reserved. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/app_name"
+ style="@style/Title" />
+ <EditText
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textUri"
+ android:hint="@string/media_content_hint"
+ android:gravity="center"
+ android:textSize="24sp" />
+ <EditText
+ android:id="@+id/next_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textNoSuggestions"
+ android:hint="@string/media_next_hint"
+ android:gravity="center"
+ android:textSize="24sp" />
+ <CheckBox
+ android:id="@+id/has_video"
+ android:layout_marginRight="8dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/has_video" />
+ <LinearLayout
+ android:id="@+id/controls"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+ <Button
+ android:id="@+id/start_button"
+ style="@style/BottomBarButton"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/start_button" />
+ <Button
+ android:id="@+id/play_button"
+ style="@style/BottomBarButton"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/play_button" />
+ </LinearLayout>
+ <TextView
+ android:id="@+id/status"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/OneMedia/res/menu/main.xml b/tests/OneMedia/res/menu/main.xml
new file mode 100644
index 0000000..c002028
--- /dev/null
+++ b/tests/OneMedia/res/menu/main.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never"
+ android:title="@string/action_settings"/>
+
+</menu>
diff --git a/tests/OneMedia/res/values/colors.xml b/tests/OneMedia/res/values/colors.xml
new file mode 100644
index 0000000..9b9dc2a
--- /dev/null
+++ b/tests/OneMedia/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.
+ */
+-->
+
+<resources>
+ <color name="title_color">#33B5E5</color>
+</resources>
diff --git a/tests/OneMedia/res/values/dimens.xml b/tests/OneMedia/res/values/dimens.xml
new file mode 100644
index 0000000..562edef
--- /dev/null
+++ b/tests/OneMedia/res/values/dimens.xml
@@ -0,0 +1,9 @@
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+ <dimen name="title_size">22sp</dimen>
+ <dimen name="small_size">11sp</dimen>
+
+</resources>
diff --git a/tests/OneMedia/res/values/strings.xml b/tests/OneMedia/res/values/strings.xml
new file mode 100644
index 0000000..1b0cebb
--- /dev/null
+++ b/tests/OneMedia/res/values/strings.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">OneMedia</string>
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Test app for trying out new media components</string>
+
+ <string name="start_button">Start</string>
+ <string name="play_button">Play</string>
+ <string name="media_content_hint">Content</string>
+ <string name="media_next_hint">Next content</string>
+ <string name="has_video">Is video</string>
+ <string name="has_duration">Has duration</string>
+
+</resources>
diff --git a/tests/OneMedia/res/values/styles.xml b/tests/OneMedia/res/values/styles.xml
new file mode 100644
index 0000000..60f3139
--- /dev/null
+++ b/tests/OneMedia/res/values/styles.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ </style>
+
+ <style name="Title">
+ <item name="android:textSize">@dimen/title_size</item>
+ <item name="android:textColor">@color/title_color</item>
+ <item name="android:clickable">false</item>
+ <item name="android:longClickable">false</item>
+ </style>
+
+ <style name="Text">
+ <item name="android:textSize">@dimen/small_size</item>
+ <item name="android:textColor">@color/title_color</item>
+ <item name="android:clickable">false</item>
+ <item name="android:longClickable">false</item>
+ </style>
+
+ <style name="BottomBarButton">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:paddingTop">0dip</item>
+ <item name="android:paddingLeft">0dip</item>
+ <item name="android:paddingRight">0dip</item>
+ <item name="android:paddingBottom">0dip</item>
+ <item name="android:textSize">12sp</item>
+ <item name="android:textStyle">bold</item>
+ </style>
+</resources>
diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
new file mode 100644
index 0000000..2b14384
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
@@ -0,0 +1,22 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.onemedia;
+
+import android.media.session.MediaSessionToken;
+
+interface IPlayerCallback {
+ void onSessionChanged(in MediaSessionToken session);
+} \ No newline at end of file
diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
new file mode 100644
index 0000000..efdbe9a
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
@@ -0,0 +1,29 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.onemedia;
+
+import android.media.session.MediaSessionToken;
+import android.os.Bundle;
+
+import com.android.onemedia.IPlayerCallback;
+import com.android.onemedia.playback.IRequestCallback;
+
+interface IPlayerService {
+ MediaSessionToken getSessionToken();
+ void registerCallback(in IPlayerCallback cb);
+ void unregisterCallback(in IPlayerCallback cb);
+ void sendRequest(String action, in Bundle params, in IRequestCallback cb);
+} \ No newline at end of file
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
new file mode 100644
index 0000000..3114ca9
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+
+import android.app.Activity;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.android.onemedia.playback.Renderer;
+
+public class OnePlayerActivity extends Activity {
+ private static final String TAG = "OnePlayerActivity";
+
+ protected PlayerController mPlayer;
+
+ private Button mStartButton;
+ private Button mPlayButton;
+ private TextView mStatusView;
+
+ private EditText mContentText;
+ private EditText mNextContentText;
+ private CheckBox mHasVideo;
+
+ private int mPlaybackState;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_one_player);
+ mPlayer = new PlayerController(this, OnePlayerService.getServiceIntent(this));
+
+
+ mStartButton = (Button) findViewById(R.id.start_button);
+ mPlayButton = (Button) findViewById(R.id.play_button);
+ mStatusView = (TextView) findViewById(R.id.status);
+ mContentText = (EditText) findViewById(R.id.content);
+ mNextContentText = (EditText) findViewById(R.id.next_content);
+ mHasVideo = (CheckBox) findViewById(R.id.has_video);
+
+ mStartButton.setOnClickListener(mButtonListener);
+ mPlayButton.setOnClickListener(mButtonListener);
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mPlayer.onResume();
+ mPlayer.setListener(mListener);
+ }
+
+ @Override
+ public void onPause() {
+ mPlayer.setListener(null);
+ mPlayer.onPause();
+ super.onPause();
+ }
+
+ private void setControlsEnabled(boolean enabled) {
+ mStartButton.setEnabled(enabled);
+ mPlayButton.setEnabled(enabled);
+ }
+
+ private View.OnClickListener mButtonListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.play_button:
+ Log.d(TAG, "Play button pressed, in state " + mPlaybackState);
+ if (mPlaybackState == PlaybackState.PLAYSTATE_PAUSED
+ || mPlaybackState == PlaybackState.PLAYSTATE_STOPPED) {
+ mPlayer.play();
+ } else if (mPlaybackState == PlaybackState.PLAYSTATE_PLAYING) {
+ mPlayer.pause();
+ }
+ break;
+ case R.id.start_button:
+ Log.d(TAG, "Start button pressed, in state " + mPlaybackState);
+ mPlayer.setContent(mContentText.getText().toString());
+ break;
+ }
+
+ }
+ };
+
+ private PlayerController.Listener mListener = new PlayerController.Listener() {
+ @Override
+ public void onPlaybackStateChange(PlaybackState state) {
+ mPlaybackState = state.getState();
+ boolean enablePlay = false;
+ StringBuilder statusBuilder = new StringBuilder();
+ switch (mPlaybackState) {
+ case PlaybackState.PLAYSTATE_PLAYING:
+ statusBuilder.append("playing");
+ mPlayButton.setText("Pause");
+ enablePlay = true;
+ break;
+ case PlaybackState.PLAYSTATE_PAUSED:
+ statusBuilder.append("paused");
+ mPlayButton.setText("Play");
+ enablePlay = true;
+ break;
+ case PlaybackState.PLAYSTATE_STOPPED:
+ statusBuilder.append("ended");
+ mPlayButton.setText("Play");
+ enablePlay = true;
+ break;
+ case PlaybackState.PLAYSTATE_ERROR:
+ statusBuilder.append("error: ").append(state.getErrorMessage());
+ break;
+ case PlaybackState.PLAYSTATE_BUFFERING:
+ statusBuilder.append("buffering");
+ break;
+ case PlaybackState.PLAYSTATE_NONE:
+ statusBuilder.append("none");
+ break;
+ default:
+ statusBuilder.append(mPlaybackState);
+ }
+ statusBuilder.append(" -- At position: ").append(state.getPosition());
+ mStatusView.setText(statusBuilder.toString());
+ mPlayButton.setEnabled(enablePlay);
+ }
+
+ @Override
+ public void onConnectionStateChange(int state) {
+ if (state == PlayerController.STATE_DISCONNECTED) {
+ setControlsEnabled(false);
+ } else if (state == PlayerController.STATE_CONNECTED) {
+ setControlsEnabled(true);
+ }
+ }
+
+ @Override
+ public void onMetadataChange(MediaMetadata metadata) {
+ Log.d(TAG, "Metadata update! Title: " + metadata);
+ }
+ };
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
new file mode 100644
index 0000000..573f7ff
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.ArrayList;
+
+public class OnePlayerService extends PlayerService {
+ private static final String TAG = "OnePlayerService";
+
+ public static Intent getServiceIntent(Context context) {
+ return new Intent(context, OnePlayerService.class).setPackage(
+ OnePlayerService.class.getPackage().getName());
+ }
+
+ @Override
+ protected Intent onCreateServiceIntent() {
+ return getServiceIntent(this);
+ }
+
+ @Override
+ protected ArrayList<String> getAllowedPackages() {
+ ArrayList<String> allowedPackages = new ArrayList<String>();
+ allowedPackages.add("com.android.onemedia");
+ return allowedPackages;
+ }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
new file mode 100644
index 0000000..e831ec6
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
@@ -0,0 +1,209 @@
+
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.media.session.MediaController;
+import android.media.session.MediaMetadata;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.media.session.TransportController;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.util.Log;
+
+import com.android.onemedia.playback.RequestUtils;
+
+public class PlayerController {
+ private static final String TAG = "PlayerController";
+
+ public static final int STATE_DISCONNECTED = 0;
+ public static final int STATE_CONNECTED = 1;
+
+ protected MediaController mController;
+ protected IPlayerService mBinder;
+ protected TransportController mTransportControls;
+
+ private final Intent mServiceIntent;
+ private Context mContext;
+ private Listener mListener;
+ private TransportListener mTransportListener = new TransportListener();
+ private SessionCallback mControllerCb;
+ private MediaSessionManager mManager;
+ private Handler mHandler = new Handler();
+
+ private boolean mResumed;
+
+ public PlayerController(Context context, Intent serviceIntent) {
+ mContext = context;
+ if (serviceIntent == null) {
+ mServiceIntent = new Intent(mContext, PlayerService.class);
+ } else {
+ mServiceIntent = serviceIntent;
+ }
+ mControllerCb = new SessionCallback();
+ mManager = (MediaSessionManager) context
+ .getSystemService(Context.MEDIA_SESSION_SERVICE);
+
+ mResumed = false;
+ }
+
+ public void setListener(Listener listener) {
+ mListener = listener;
+ Log.d(TAG, "Listener set to " + listener + " session is " + mController);
+ if (mListener != null) {
+ mHandler = new Handler();
+ mListener.onConnectionStateChange(
+ mController == null ? STATE_DISCONNECTED : STATE_CONNECTED);
+ }
+ }
+
+ public void onResume() {
+ mResumed = true;
+ Log.d(TAG, "onResume. Binding to service with intent " + mServiceIntent.toString());
+ bindToService();
+ }
+
+ public void onPause() {
+ mResumed = false;
+ Log.d(TAG, "onPause, unbinding from service");
+ unbindFromService();
+ }
+
+ public void play() {
+ if (mTransportControls != null) {
+ mTransportControls.play();
+ }
+ }
+
+ public void pause() {
+ if (mTransportControls != null) {
+ mTransportControls.pause();
+ }
+ }
+
+ public void setContent(String source) {
+ RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
+ bob.setSource(source);
+ try {
+ mBinder.sendRequest(RequestUtils.ACTION_SET_CONTENT, bob.build(), null);
+ } catch (RemoteException e) {
+ Log.d(TAG, "setContent failed, service may have died.", e);
+ }
+ }
+
+ public void setNextContent(String source) {
+ RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
+ bob.setSource(source);
+ try {
+ mBinder.sendRequest(RequestUtils.ACTION_SET_NEXT_CONTENT, bob.build(), null);
+ } catch (RemoteException e) {
+ Log.d(TAG, "setNexctContent failed, service may have died.", e);
+ }
+ }
+
+ private void unbindFromService() {
+ mContext.unbindService(mServiceConnection);
+ }
+
+ private void bindToService() {
+ mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ private ServiceConnection mServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ if (mController != null) {
+ mController.removeCallback(mControllerCb);
+ }
+ mBinder = null;
+ mController = null;
+ mTransportControls = null;
+ Log.d(TAG, "Disconnected from PlayerService");
+
+ if (mListener != null) {
+ mListener.onConnectionStateChange(STATE_DISCONNECTED);
+ }
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mBinder = IPlayerService.Stub.asInterface(service);
+ Log.d(TAG, "service is " + service + " binder is " + mBinder);
+ try {
+ mController = MediaController.fromToken(mBinder.getSessionToken());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error getting session", e);
+ return;
+ }
+ mController.addCallback(mControllerCb, mHandler);
+ mTransportControls = mController.getTransportController();
+ if (mTransportControls != null) {
+ mTransportControls.addStateListener(mTransportListener);
+ }
+ Log.d(TAG, "Ready to use PlayerService");
+
+ if (mListener != null) {
+ mListener.onConnectionStateChange(STATE_CONNECTED);
+ if (mTransportControls != null) {
+ mListener.onPlaybackStateChange(mTransportControls.getPlaybackState());
+ }
+ }
+ }
+ };
+
+ private class SessionCallback extends MediaController.Callback {
+ @Override
+ public void onRouteChanged(Bundle route) {
+ // TODO
+ }
+ }
+
+ private class TransportListener extends TransportController.TransportStateListener {
+ @Override
+ public void onPlaybackStateChanged(PlaybackState state) {
+ if (state == null) {
+ return;
+ }
+ Log.d(TAG, "Received playback state change to state " + state.getState());
+ if (mListener != null) {
+ mListener.onPlaybackStateChange(state);
+ }
+ }
+
+ @Override
+ public void onMetadataChanged(MediaMetadata metadata) {
+ if (metadata == null) {
+ return;
+ }
+ Log.d(TAG, "Received metadata change, title is "
+ + metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+ }
+ }
+
+ public interface Listener {
+ public void onPlaybackStateChange(PlaybackState state);
+ public void onMetadataChange(MediaMetadata metadata);
+ public void onConnectionStateChange(int state);
+ }
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerService.java b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
new file mode 100644
index 0000000..0ad6dd1
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.app.Service;
+import android.content.Intent;
+import android.media.session.MediaSessionToken;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.onemedia.playback.IRequestCallback;
+import com.android.onemedia.playback.RequestUtils;
+
+import java.util.ArrayList;
+
+public class PlayerService extends Service {
+ private static final String TAG = "PlayerService";
+
+ private PlayerBinder mBinder;
+ private PlayerSession mSession;
+ private Intent mIntent;
+ private boolean mStarted = false;
+
+ private ArrayList<IPlayerCallback> mCbs = new ArrayList<IPlayerCallback>();
+
+ @Override
+ public void onCreate() {
+ Log.d(TAG, "onCreate");
+ mIntent = onCreateServiceIntent();
+ if (mSession == null) {
+ mSession = onCreatePlayerController();
+ mSession.createSession();
+ mSession.setListener(mPlayerListener);
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (mBinder == null) {
+ mBinder = new PlayerBinder();
+ }
+ return mBinder;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.d(TAG, "onStartCommand");
+ return START_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG, "onDestroy");
+ mSession.onDestroy();
+ mSession = null;
+ }
+
+ public void onPlaybackStarted() {
+ if (!mStarted) {
+ Log.d(TAG, "Starting self");
+ startService(onCreateServiceIntent());
+ mStarted = true;
+ }
+ }
+
+ public void onPlaybackEnded() {
+ if (mStarted) {
+ Log.d(TAG, "Stopping self");
+ stopSelf();
+ mStarted = false;
+ }
+ }
+
+ protected Intent onCreateServiceIntent() {
+ return new Intent(this, PlayerService.class).setPackage(getBasePackageName());
+ }
+
+ protected PlayerSession onCreatePlayerController() {
+ return new PlayerSession(this);
+ }
+
+ protected ArrayList<String> getAllowedPackages() {
+ return null;
+ }
+
+ private final PlayerSession.Listener mPlayerListener = new PlayerSession.Listener() {
+ @Override
+ public void onPlayStateChanged(PlaybackState state) {
+ switch (state.getState()) {
+ case PlaybackState.PLAYSTATE_PLAYING:
+ onPlaybackStarted();
+ break;
+ case PlaybackState.PLAYSTATE_STOPPED:
+ case PlaybackState.PLAYSTATE_ERROR:
+ onPlaybackEnded();
+ break;
+ }
+ }
+ };
+
+ public class PlayerBinder extends IPlayerService.Stub {
+ @Override
+ public void sendRequest(String action, Bundle params, IRequestCallback cb) {
+ if (RequestUtils.ACTION_SET_CONTENT.equals(action)) {
+ mSession.setContent(params);
+ } else if (RequestUtils.ACTION_SET_NEXT_CONTENT.equals(action)) {
+ mSession.setNextContent(params);
+ }
+ }
+
+ @Override
+ public void registerCallback(final IPlayerCallback cb) throws RemoteException {
+ if (!mCbs.contains(cb)) {
+ mCbs.add(cb);
+ cb.asBinder().linkToDeath(new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ mCbs.remove(cb);
+ }
+ }, 0);
+ }
+ try {
+ cb.onSessionChanged(getSessionToken());
+ } catch (RemoteException e) {
+ mCbs.remove(cb);
+ throw e;
+ }
+ }
+
+ @Override
+ public void unregisterCallback(IPlayerCallback cb) throws RemoteException {
+ mCbs.remove(cb);
+ }
+
+ @Override
+ public MediaSessionToken getSessionToken() throws RemoteException {
+ return mSession.getSessionToken();
+ }
+ }
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
new file mode 100644
index 0000000..a2d7897
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.content.Context;
+import android.content.Intent;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionToken;
+import android.media.session.PlaybackState;
+import android.media.session.TransportPerformer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.android.onemedia.playback.LocalRenderer;
+import com.android.onemedia.playback.Renderer;
+import com.android.onemedia.playback.RendererFactory;
+
+public class PlayerSession {
+ private static final String TAG = "PlayerSession";
+
+ protected MediaSession mSession;
+ protected Context mContext;
+ protected RendererFactory mRendererFactory;
+ protected LocalRenderer mRenderer;
+ protected MediaSession.Callback mCallback;
+ protected Renderer.Listener mRenderListener;
+ protected TransportPerformer mPerformer;
+
+ protected PlaybackState mPlaybackState;
+ protected Listener mListener;
+
+ public PlayerSession(Context context) {
+ mContext = context;
+ mRendererFactory = new RendererFactory();
+ mRenderer = new LocalRenderer(context, null);
+ mCallback = new ControllerCb();
+ mRenderListener = new RenderListener();
+ mPlaybackState = new PlaybackState();
+ mPlaybackState.setActions(PlaybackState.ACTION_PAUSE
+ | PlaybackState.ACTION_PLAY);
+
+ mRenderer.registerListener(mRenderListener);
+ }
+
+ public void createSession() {
+ if (mSession != null) {
+ mSession.release();
+ }
+ MediaSessionManager man = (MediaSessionManager) mContext
+ .getSystemService(Context.MEDIA_SESSION_SERVICE);
+ Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
+ mSession = man.createSession("OneMedia");
+ mSession.addCallback(mCallback);
+ mPerformer = mSession.setTransportPerformerEnabled();
+ mPerformer.addListener(new TransportListener());
+ mPerformer.setPlaybackState(mPlaybackState);
+ mSession.publish();
+ }
+
+ public void onDestroy() {
+ if (mSession != null) {
+ mSession.release();
+ }
+ if (mRenderer != null) {
+ mRenderer.unregisterListener(mRenderListener);
+ mRenderer.onDestroy();
+ }
+ }
+
+ public void setListener(Listener listener) {
+ mListener = listener;
+ }
+
+ public MediaSessionToken getSessionToken() {
+ return mSession.getSessionToken();
+ }
+
+ public void setContent(Bundle request) {
+ mRenderer.setContent(request);
+ }
+
+ public void setNextContent(Bundle request) {
+ mRenderer.setNextContent(request);
+ }
+
+ public interface Listener {
+ public void onPlayStateChanged(PlaybackState state);
+ }
+
+ private class RenderListener implements Renderer.Listener {
+
+ @Override
+ public void onError(int type, int extra, Bundle extras, Throwable error) {
+ Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+ if (error != null) {
+ mPlaybackState.setErrorMessage(error.getLocalizedMessage());
+ }
+ mPerformer.setPlaybackState(mPlaybackState);
+ if (mListener != null) {
+ mListener.onPlayStateChanged(mPlaybackState);
+ }
+ }
+
+ @Override
+ public void onStateChanged(int newState) {
+ if (newState != Renderer.STATE_ERROR) {
+ mPlaybackState.setErrorMessage(null);
+ }
+ switch (newState) {
+ case Renderer.STATE_ENDED:
+ case Renderer.STATE_STOPPED:
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_STOPPED);
+ break;
+ case Renderer.STATE_INIT:
+ case Renderer.STATE_PREPARING:
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_BUFFERING);
+ break;
+ case Renderer.STATE_ERROR:
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+ break;
+ case Renderer.STATE_PAUSED:
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_PAUSED);
+ break;
+ case Renderer.STATE_PLAYING:
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_PLAYING);
+ break;
+ default:
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+ mPlaybackState.setErrorMessage("unkown state");
+ break;
+ }
+ mPlaybackState.setPosition(mRenderer.getSeekPosition());
+ mPerformer.setPlaybackState(mPlaybackState);
+ if (mListener != null) {
+ mListener.onPlayStateChanged(mPlaybackState);
+ }
+ }
+
+ @Override
+ public void onBufferingUpdate(int percent) {
+ }
+
+ @Override
+ public void onFocusLost() {
+ Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED);
+ mPlaybackState.setState(PlaybackState.PLAYSTATE_PAUSED);
+ mPlaybackState.setPosition(mRenderer.getSeekPosition());
+ mPerformer.setPlaybackState(mPlaybackState);
+ if (mListener != null) {
+ mListener.onPlayStateChanged(mPlaybackState);
+ }
+ }
+
+ @Override
+ public void onNextStarted() {
+ }
+
+ }
+
+ private class ControllerCb extends MediaSession.Callback {
+
+ @Override
+ public void onMediaButton(Intent mediaRequestIntent) {
+ if (Intent.ACTION_MEDIA_BUTTON.equals(mediaRequestIntent.getAction())) {
+ KeyEvent event = (KeyEvent) mediaRequestIntent
+ .getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ Log.d(TAG, "play button received");
+ mRenderer.onPlay();
+ break;
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ Log.d(TAG, "pause button received");
+ mRenderer.onPause();
+ break;
+ }
+ }
+ }
+ }
+
+ private class TransportListener extends TransportPerformer.Listener {
+ @Override
+ public void onPlay() {
+ mRenderer.onPlay();
+ }
+
+ @Override
+ public void onPause() {
+ mRenderer.onPause();
+ }
+ }
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl b/tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl
new file mode 100644
index 0000000..c5a30a8
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl
@@ -0,0 +1,22 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+
+oneway interface IRequestCallback {
+ void onResult(in Bundle result);
+} \ No newline at end of file
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
new file mode 100644
index 0000000..7f62f66
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
@@ -0,0 +1,704 @@
+package com.android.onemedia.playback;
+
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnBufferingUpdateListener;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
+import android.media.MediaPlayer.OnPreparedListener;
+import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Helper class for wrapping a MediaPlayer and doing a lot of the default work
+ * to play audio. This class is not currently thread safe and all calls to it
+ * should be made on the same thread.
+ */
+public class LocalRenderer extends Renderer implements OnPreparedListener,
+ OnBufferingUpdateListener, OnCompletionListener, OnErrorListener,
+ OnAudioFocusChangeListener {
+ private static final String TAG = "MediaPlayerManager";
+ private static final boolean DEBUG = true;
+ private static long sDebugInstanceId = 0;
+
+ private static final String[] SUPPORTED_FEATURES = {
+ FEATURE_SET_CONTENT,
+ FEATURE_SET_NEXT_CONTENT,
+ FEATURE_PLAY,
+ FEATURE_PAUSE,
+ FEATURE_NEXT,
+ FEATURE_PREVIOUS,
+ FEATURE_SEEK_TO,
+ FEATURE_STOP
+ };
+
+ /**
+ * These are the states where it is valid to call play directly on the
+ * MediaPlayer.
+ */
+ private static final int CAN_PLAY = STATE_READY | STATE_PAUSED | STATE_ENDED;
+ /**
+ * These are the states where we expect the MediaPlayer to be ready in the
+ * future, so we can set a flag to start playing when it is.
+ */
+ private static final int CAN_READY_PLAY = STATE_INIT | STATE_PREPARING;
+ /**
+ * The states when it is valid to call pause on the MediaPlayer.
+ */
+ private static final int CAN_PAUSE = STATE_PLAYING;
+ /**
+ * The states where it is valid to call seek on the MediaPlayer.
+ */
+ private static final int CAN_SEEK = STATE_READY | STATE_PLAYING | STATE_PAUSED | STATE_ENDED;
+ /**
+ * The states where we expect the MediaPlayer to be ready in the future and
+ * can store a seek position to set later.
+ */
+ private static final int CAN_READY_SEEK = STATE_INIT | STATE_PREPARING;
+ /**
+ * The states where it is valid to call stop on the MediaPlayer.
+ */
+ private static final int CAN_STOP = STATE_READY | STATE_PLAYING | STATE_PAUSED | STATE_ENDED;
+ /**
+ * The states where it is valid to get the current play position and the
+ * duration from the MediaPlayer.
+ */
+ private static final int CAN_GET_POSITION = STATE_READY | STATE_PLAYING | STATE_PAUSED;
+
+
+
+ private class PlayerContent {
+ public final String source;
+ public final Map<String, String> headers;
+
+ public PlayerContent(String source, Map<String, String> headers) {
+ this.source = source;
+ this.headers = headers;
+ }
+ }
+
+ private class AsyncErrorRetriever extends AsyncTask<HttpGet, Void, Void> {
+ private final long errorId;
+ private boolean closeHttpClient;
+
+ public AsyncErrorRetriever(long errorId) {
+ this.errorId = errorId;
+ closeHttpClient = false;
+ }
+
+ public boolean cancelRequestLocked(boolean closeHttp) {
+ closeHttpClient = closeHttp;
+ return this.cancel(false);
+ }
+
+ @Override
+ protected Void doInBackground(HttpGet[] params) {
+ synchronized (mErrorLock) {
+ if (isCancelled() || mHttpClient == null) {
+ if (mErrorRetriever == this) {
+ mErrorRetriever = null;
+ }
+ return null;
+ }
+ mSafeToCloseClient = false;
+ }
+ final PlaybackError error = new PlaybackError();
+ try {
+ HttpResponse response = mHttpClient.execute(params[0]);
+ synchronized (mErrorLock) {
+ if (mErrorId != errorId || mError == null) {
+ // A new error has occurred, abort
+ return null;
+ }
+ error.type = mError.type;
+ error.extra = mError.extra;
+ error.errorMessage = mError.errorMessage;
+ }
+ final int code = response.getStatusLine().getStatusCode();
+ if (code >= 300) {
+ error.extra = code;
+ }
+ final Bundle errorExtras = new Bundle();
+ Header[] headers = response.getAllHeaders();
+ if (headers != null && headers.length > 0) {
+ for (Header header : headers) {
+ errorExtras.putString(header.getName(), header.getValue());
+ }
+ error.errorExtras = errorExtras;
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "IOException requesting from server, unable to get more exact error");
+ } finally {
+ synchronized (mErrorLock) {
+ mSafeToCloseClient = true;
+ if (mErrorRetriever == this) {
+ mErrorRetriever = null;
+ }
+ if (isCancelled()) {
+ if (closeHttpClient) {
+ mHttpClient.close();
+ mHttpClient = null;
+ }
+ return null;
+ }
+ }
+ }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mErrorLock) {
+ if (mErrorId == errorId) {
+ setError(error.type, error.extra, error.errorExtras, null);
+ }
+ }
+ }
+ });
+ return null;
+ }
+ }
+
+ private int mState = STATE_INIT;
+
+ private AudioManager mAudioManager;
+ private MediaPlayer mPlayer;
+ private PlayerContent mContent;
+ private MediaPlayer mNextPlayer;
+ private PlayerContent mNextContent;
+ private SurfaceHolder mHolder;
+ private SurfaceHolder.Callback mHolderCB;
+ private Context mContext;
+
+ private Handler mHandler = new Handler();
+
+ private AndroidHttpClient mHttpClient = AndroidHttpClient.newInstance("TUQ");
+ // The ongoing error request thread if there is one. This should only be
+ // modified while mErrorLock is held.
+ private AsyncErrorRetriever mErrorRetriever;
+ // This is set to false while a server request is being made to retrieve
+ // the current error. It should only be set while mErrorLock is held.
+ private boolean mSafeToCloseClient = true;
+ private final Object mErrorLock = new Object();
+ // A tracking id for the current error. This should only be modified while
+ // mErrorLock is held.
+ private long mErrorId = 0;
+ // The current error state of this player. This is cleared when the state
+ // leaves an error state and set when it enters one. This should only be
+ // modified when mErrorLock is held.
+ private PlaybackError mError;
+
+ private boolean mPlayOnReady;
+ private int mSeekOnReady;
+ private boolean mHasAudioFocus;
+ private long mDebugId = sDebugInstanceId++;
+
+ public LocalRenderer(Context context, Bundle params) {
+ super(context, params);
+ mContext = context;
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ }
+
+ @Override
+ protected void initFeatures(Bundle params) {
+ for (String feature : SUPPORTED_FEATURES) {
+ mFeatures.add(feature);
+ }
+ }
+
+ /**
+ * Call this when completely finished with the MediaPlayerManager to have it
+ * clean up. The instance may not be used again after this is called.
+ */
+ @Override
+ public void onDestroy() {
+ synchronized (mErrorLock) {
+ if (DEBUG) {
+ Log.d(TAG, "onDestroy, error retriever? " + mErrorRetriever + " safe to close? "
+ + mSafeToCloseClient + " client? " + mHttpClient);
+ }
+ if (mErrorRetriever != null) {
+ mErrorRetriever.cancelRequestLocked(true);
+ mErrorRetriever = null;
+ }
+ // Increment the error id to ensure no errors are sent after this
+ // point.
+ mErrorId++;
+ if (mSafeToCloseClient) {
+ mHttpClient.close();
+ mHttpClient = null;
+ }
+ }
+ }
+
+ @Override
+ public void onPrepared(MediaPlayer player) {
+ if (!isCurrentPlayer(player)) {
+ return;
+ }
+ setState(STATE_READY);
+ if (DEBUG) {
+ Log.d(TAG, mDebugId + ": Finished preparing, seekOnReady is " + mSeekOnReady);
+ }
+ if (mSeekOnReady >= 0) {
+ onSeekTo(mSeekOnReady);
+ mSeekOnReady = -1;
+ }
+ if (mPlayOnReady) {
+ player.start();
+ setState(STATE_PLAYING);
+ }
+ }
+
+ @Override
+ public void onBufferingUpdate(MediaPlayer player, int percent) {
+ if (!isCurrentPlayer(player)) {
+ return;
+ }
+ pushOnBufferingUpdate(percent);
+ }
+
+ @Override
+ public void onCompletion(MediaPlayer player) {
+ if (!isCurrentPlayer(player)) {
+ return;
+ }
+ if (DEBUG) {
+ Log.d(TAG, mDebugId + ": Completed item. Have next item? " + (mNextPlayer != null));
+ }
+ if (mNextPlayer != null) {
+ if (mPlayer != null) {
+ mPlayer.release();
+ }
+ mPlayer = mNextPlayer;
+ mContent = mNextContent;
+ mNextPlayer = null;
+ mNextContent = null;
+ pushOnNextStarted();
+ return;
+ }
+ setState(STATE_ENDED);
+ }
+
+ @Override
+ public boolean onError(MediaPlayer player, int what, int extra) {
+ if (!isCurrentPlayer(player)) {
+ return false;
+ }
+ if (DEBUG) {
+ Log.d(TAG, mDebugId + ": Entered error state, what: " + what + " extra: " + extra);
+ }
+ synchronized (mErrorLock) {
+ ++mErrorId;
+ mError = new PlaybackError();
+ mError.type = what;
+ mError.extra = extra;
+ }
+
+ if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN && extra == MediaPlayer.MEDIA_ERROR_IO
+ && mContent != null && mContent.source.startsWith("http")) {
+ HttpGet request = new HttpGet(mContent.source);
+ if (mContent.headers != null) {
+ for (String key : mContent.headers.keySet()) {
+ request.addHeader(key, mContent.headers.get(key));
+ }
+ }
+ synchronized (mErrorLock) {
+ if (mErrorRetriever != null) {
+ mErrorRetriever.cancelRequestLocked(false);
+ }
+ mErrorRetriever = new AsyncErrorRetriever(mErrorId);
+ mErrorRetriever.execute(request);
+ }
+ } else {
+ setError(what, extra, null, null);
+ }
+ return true;
+ }
+
+ @Override
+ public void onAudioFocusChange(int focusChange) {
+ // TODO figure out appropriate logic for handling focus loss at the TUQ
+ // level.
+ switch (focusChange) {
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ if (mState == STATE_PLAYING) {
+ onPause();
+ mPlayOnReady = true;
+ }
+ mHasAudioFocus = false;
+ break;
+ case AudioManager.AUDIOFOCUS_LOSS:
+ if (mState == STATE_PLAYING) {
+ onPause();
+ mPlayOnReady = false;
+ }
+ pushOnFocusLost();
+ mHasAudioFocus = false;
+ break;
+ case AudioManager.AUDIOFOCUS_GAIN:
+ mHasAudioFocus = true;
+ if (mPlayOnReady) {
+ onPlay();
+ }
+ break;
+ default:
+ Log.d(TAG, "Unknown focus change event " + focusChange);
+ break;
+ }
+ }
+
+ @Override
+ public void setContent(Bundle request) {
+ setContent(request, null);
+ }
+
+ /**
+ * Prepares the player for the given playback request. If the holder is null
+ * it is assumed this is an audio only source. If playOnReady is set to true
+ * the media will begin playing as soon as it can.
+ */
+ public void setContent(Bundle request, SurfaceHolder holder) {
+ String source = request.getString(RequestUtils.EXTRA_KEY_SOURCE);
+ Map<String, String> headers = null; // request.mHeaders;
+ boolean playOnReady = true; // request.mPlayOnReady;
+ if (DEBUG) {
+ Log.d(TAG, mDebugId + ": Settings new content. Have a player? " + (mPlayer != null)
+ + " have a next player? " + (mNextPlayer != null));
+ }
+ cleanUpPlayer();
+ setState(STATE_PREPARING);
+ mPlayOnReady = playOnReady;
+ mSeekOnReady = -1;
+ final MediaPlayer newPlayer = new MediaPlayer();
+
+ requestAudioFocus();
+
+ mPlayer = newPlayer;
+ mContent = new PlayerContent(source, headers);
+ try {
+ if (headers != null) {
+ Uri sourceUri = Uri.parse(source);
+ newPlayer.setDataSource(mContext, sourceUri, headers);
+ } else {
+ newPlayer.setDataSource(source);
+ }
+ } catch (Exception e) {
+ setError(Listener.ERROR_LOAD_FAILED, 0, null, e);
+ return;
+ }
+ if (isHolderReady(holder, newPlayer)) {
+ preparePlayer(newPlayer, true);
+ }
+ }
+
+ @Override
+ public void setNextContent(Bundle request) {
+ String source = request.getString(RequestUtils.EXTRA_KEY_SOURCE);
+ Map<String, String> headers = null; // request.mHeaders;
+
+ // TODO support video
+
+ if (DEBUG) {
+ Log.d(TAG, mDebugId + ": Setting next content. Have player? " + (mPlayer != null)
+ + " have next player? " + (mNextPlayer != null));
+ }
+
+ if (mPlayer == null) {
+ // The manager isn't being used to play anything, don't try to
+ // set a next.
+ return;
+ }
+ if (mNextPlayer != null) {
+ // Before setting up the new one clear out the old one and release
+ // it to ensure it doesn't play.
+ mPlayer.setNextMediaPlayer(null);
+ mNextPlayer.release();
+ mNextPlayer = null;
+ mNextContent = null;
+ }
+ if (source == null) {
+ // If there's no new content we're done
+ return;
+ }
+ final MediaPlayer newPlayer = new MediaPlayer();
+
+ try {
+ if (headers != null) {
+ Uri sourceUri = Uri.parse(source);
+ newPlayer.setDataSource(mContext, sourceUri, headers);
+ } else {
+ newPlayer.setDataSource(source);
+ }
+ } catch (Exception e) {
+ newPlayer.release();
+ // Don't return an error until we get to this item in playback
+ return;
+ }
+
+ if (preparePlayer(newPlayer, false)) {
+ mPlayer.setNextMediaPlayer(newPlayer);
+ mNextPlayer = newPlayer;
+ mNextContent = new PlayerContent(source, headers);
+ }
+ }
+
+ private void requestAudioFocus() {
+ int result = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN);
+ mHasAudioFocus = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
+ }
+
+ /**
+ * Start the player if possible or queue it to play when ready. If the
+ * player is in a state where it will never be ready returns false.
+ *
+ * @return true if the content was started or will be started later
+ */
+ @Override
+ public boolean onPlay() {
+ MediaPlayer player = mPlayer;
+ if (player != null && mState == STATE_PLAYING) {
+ // already playing, just return
+ return true;
+ }
+ if (!mHasAudioFocus) {
+ requestAudioFocus();
+ }
+ if (player != null && canPlay()) {
+ player.start();
+ setState(STATE_PLAYING);
+ } else if (canReadyPlay()) {
+ mPlayOnReady = true;
+ } else if (!isPlaying()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Pause the player if possible or set it to not play when ready. If the
+ * player is in a state where it will never be ready returns false.
+ *
+ * @return true if the content was paused or will wait to play when ready
+ * later
+ */
+ @Override
+ public boolean onPause() {
+ MediaPlayer player = mPlayer;
+ // If the user paused us make sure we won't start playing again until
+ // asked to
+ mPlayOnReady = false;
+ if (player != null && (mState & CAN_PAUSE) != 0) {
+ player.pause();
+ setState(STATE_PAUSED);
+ } else if (!isPaused()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Seek to a given position in the media. If the seek succeeded or will be
+ * performed when loading is complete returns true. If the position is not
+ * in range or the player will never be ready returns false.
+ *
+ * @param position The position to seek to in milliseconds
+ * @return true if playback was moved or will be moved when ready
+ */
+ @Override
+ public boolean onSeekTo(int position) {
+ MediaPlayer player = mPlayer;
+ if (player != null && (mState & CAN_SEEK) != 0) {
+ if (position < 0 || position >= getDuration()) {
+ return false;
+ } else {
+ if (mState == STATE_ENDED) {
+ player.start();
+ player.pause();
+ setState(STATE_PAUSED);
+ }
+ player.seekTo(position);
+ }
+ } else if ((mState & CAN_READY_SEEK) != 0) {
+ mSeekOnReady = position;
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Stop the player. It cannot be used again until
+ * {@link #setContent(String, boolean)} is called.
+ *
+ * @return true if stopping the player succeeded
+ */
+ @Override
+ public boolean onStop() {
+ cleanUpPlayer();
+ setState(STATE_STOPPED);
+ return true;
+ }
+
+ public boolean isPlaying() {
+ return mState == STATE_PLAYING;
+ }
+
+ public boolean isPaused() {
+ return mState == STATE_PAUSED;
+ }
+
+ @Override
+ public long getSeekPosition() {
+ return ((mState & CAN_GET_POSITION) == 0) ? -1 : mPlayer.getCurrentPosition();
+ }
+
+ @Override
+ public long getDuration() {
+ return ((mState & CAN_GET_POSITION) == 0) ? -1 : mPlayer.getDuration();
+ }
+
+ private boolean canPlay() {
+ return ((mState & CAN_PLAY) != 0) && mHasAudioFocus;
+ }
+
+ private boolean canReadyPlay() {
+ return (mState & CAN_PLAY) != 0 || (mState & CAN_READY_PLAY) != 0;
+ }
+
+ /**
+ * Sends a state update if the listener exists
+ */
+ private void setState(int state) {
+ if (state == mState) {
+ return;
+ }
+ Log.d(TAG, "Entering state " + state + " from state " + mState);
+ mState = state;
+ if (state != STATE_ERROR) {
+ // Don't notify error here, it'll get sent via onError
+ pushOnStateChanged(state);
+ }
+ }
+
+ private boolean preparePlayer(final MediaPlayer player, boolean current) {
+ player.setOnPreparedListener(this);
+ player.setOnBufferingUpdateListener(this);
+ player.setOnCompletionListener(this);
+ player.setOnErrorListener(this);
+ try {
+ player.prepareAsync();
+ if (current) {
+ setState(STATE_PREPARING);
+ }
+ } catch (IllegalStateException e) {
+ if (current) {
+ setError(Listener.ERROR_PREPARE_ERROR, 0, null, e);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @param extra
+ * @param e
+ */
+ private void setError(int type, int extra, Bundle extras, Exception e) {
+ setState(STATE_ERROR);
+ pushOnError(type, extra, extras, e);
+ cleanUpPlayer();
+ return;
+ }
+
+ /**
+ * Checks if the holder is ready and either sets up a callback to wait for
+ * it or sets it directly. If
+ *
+ * @param holder
+ * @param player
+ * @return
+ */
+ private boolean isHolderReady(final SurfaceHolder holder, final MediaPlayer player) {
+ mHolder = holder;
+ if (holder != null) {
+ if (holder.getSurface() != null && holder.getSurface().isValid()) {
+ player.setDisplay(holder);
+ return true;
+ } else {
+ Log.w(TAG, "Holder not null, waiting for it to be ready");
+ // If the holder isn't ready yet add a callback to set the
+ // holder when it's ready.
+ SurfaceHolder.Callback cb = new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceDestroyed(SurfaceHolder arg0) {
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder arg0) {
+ if (player.equals(mPlayer)) {
+ player.setDisplay(arg0);
+ preparePlayer(player, true);
+ }
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
+ }
+ };
+ mHolderCB = cb;
+ holder.addCallback(cb);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void cleanUpPlayer() {
+ if (DEBUG) {
+ Log.d(TAG, mDebugId + ": Cleaning up current player");
+ }
+ synchronized (mErrorLock) {
+ mError = null;
+ if (mErrorRetriever != null) {
+ mErrorRetriever.cancelRequestLocked(false);
+ // Don't set to null as we may need to cancel again with true if
+ // the object gets destroyed.
+ }
+ }
+ mAudioManager.abandonAudioFocus(this);
+
+ SurfaceHolder.Callback cb = mHolderCB;
+ mHolderCB = null;
+ SurfaceHolder holder = mHolder;
+ mHolder = null;
+ if (holder != null && cb != null) {
+ holder.removeCallback(cb);
+ }
+
+ MediaPlayer player = mPlayer;
+ mPlayer = null;
+ if (player != null) {
+ player.reset();
+ player.release();
+ }
+ }
+
+ private boolean isCurrentPlayer(MediaPlayer player) {
+ return player.equals(mPlayer);
+ }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java b/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java
new file mode 100644
index 0000000..f9e6794
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java
@@ -0,0 +1,59 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.v7.media.MediaItemMetadata;
+
+/**
+ * TODO: Insert description here. (generated by epastern)
+ */
+public class MediaItem implements Parcelable {
+ private Bundle mBundle;
+
+ public MediaItem() {
+
+ }
+
+ private MediaItem(Parcel in) {
+ mBundle = in.readBundle();
+ }
+
+ public String getTitle() {
+ return mBundle.getString(MediaItemMetadata.KEY_TITLE);
+ }
+
+ public String getArtist() {
+ return mBundle.getString(MediaItemMetadata.KEY_ALBUM_ARTIST);
+ }
+
+ /* (non-Javadoc)
+ * @see android.os.Parcelable#describeContents()
+ */
+ @Override
+ public int describeContents() {
+ // TODO(epastern): Auto-generated method stub
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeBundle(mBundle);
+ }
+
+ public static final Parcelable.Creator<MediaItem> CREATOR
+ = new Parcelable.Creator<MediaItem>() {
+ public MediaItem createFromParcel(Parcel in) {
+ return new MediaItem(in);
+ }
+
+ public MediaItem[] newArray(int size) {
+ return new MediaItem[size];
+ }
+ };
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java b/tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java
new file mode 100644
index 0000000..72d936c
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java
@@ -0,0 +1,10 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+
+public class PlaybackError {
+ public int type;
+ public int extra;
+ public String errorMessage;
+ public Bundle errorExtras;
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/Renderer.java b/tests/OneMedia/src/com/android/onemedia/playback/Renderer.java
new file mode 100644
index 0000000..2451bdf
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/Renderer.java
@@ -0,0 +1,199 @@
+package com.android.onemedia.playback;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TODO: Insert description here. (generated by epastern)
+ */
+public abstract class Renderer {
+ public static final String FEATURE_SET_CONTENT = "com.android.media.SET_CONTENT";
+ public static final String FEATURE_SET_NEXT_CONTENT = "com.android.media.SET_NEXT_CONTENT";
+ public static final String FEATURE_PLAY = "com.android.media.PLAY";
+ public static final String FEATURE_PAUSE = "com.android.media.PAUSE";
+ public static final String FEATURE_NEXT = "com.android.media.NEXT";
+ public static final String FEATURE_PREVIOUS = "com.android.media.PREVIOUS";
+ public static final String FEATURE_SEEK_TO = "com.android.media.SEEK_TO";
+ public static final String FEATURE_STOP = "com.android.media.STOP";
+ // TODO move states somewhere else
+ public static final int STATE_ERROR = 0;
+ /**
+ * The state MediaPlayerManager starts in before any action has been
+ * performed.
+ */
+ public static final int STATE_INIT = 1 << 0;
+ /**
+ * Indicates the source has been set and it is being prepared/buffered
+ * before starting playback.
+ */
+ public static final int STATE_PREPARING = 1 << 1;
+ /**
+ * The media is ready and playback can be started.
+ */
+ public static final int STATE_READY = 1 << 2;
+ /**
+ * The media is currently playing.
+ */
+ public static final int STATE_PLAYING = 1 << 3;
+ /**
+ * The media is currently paused.
+ */
+ public static final int STATE_PAUSED = 1 << 4;
+ /**
+ * The service has been stopped and cannot be started again until a new
+ * source has been set.
+ */
+ public static final int STATE_STOPPED = 1 << 5;
+ /**
+ * The playback has reached the end. It can be restarted by calling play().
+ */
+ public static final int STATE_ENDED = 1 << 6;
+
+ // TODO decide on proper way of describing features
+ protected List<String> mFeatures = new ArrayList<String>();
+ protected List<Listener> mListeners = new ArrayList<Listener>();
+
+ public Renderer(Context context, Bundle params) {
+ onCreate(params);
+ initFeatures(params);
+ }
+
+ abstract public void setContent(Bundle request);
+
+ public void onCreate(Bundle params) {
+ // Do nothing by default
+ }
+
+ public void setNextContent(Bundle request) {
+ throw new UnsupportedOperationException("setNextContent() is not supported.");
+ }
+
+ public List<String> getFeatures() {
+ return mFeatures;
+ }
+
+ public boolean onPlay() {
+ throw new UnsupportedOperationException("play is not supported.");
+ }
+
+ public boolean onPause() {
+ throw new UnsupportedOperationException("pause is not supported.");
+ }
+
+ public boolean onNext() {
+ throw new UnsupportedOperationException("next is not supported.");
+ }
+
+ public boolean onPrevious() {
+ throw new UnsupportedOperationException("previous is not supported.");
+ }
+
+ public boolean onStop() {
+ throw new UnsupportedOperationException("stop is not supported.");
+ }
+
+ public boolean onSeekTo(int time) {
+ throw new UnsupportedOperationException("seekTo is not supported.");
+ }
+
+ public long getSeekPosition() {
+ throw new UnsupportedOperationException("getSeekPosition is not supported.");
+ }
+
+ public long getDuration() {
+ throw new UnsupportedOperationException("getDuration is not supported.");
+ }
+
+ public int getPlayState() {
+ throw new UnsupportedOperationException("getPlayState is not supported.");
+ }
+
+ public void onDestroy() {
+ // Do nothing by default
+ }
+
+ public void registerListener(Listener listener) {
+ if (!mListeners.contains(listener)) {
+ mListeners.add(listener);
+ }
+ }
+
+ public void unregisterListener(Listener listener) {
+ mListeners.remove(listener);
+ }
+
+ protected void initFeatures(Bundle params) {
+ mFeatures.add(FEATURE_SET_CONTENT);
+ }
+
+ protected void pushOnError(int type, int extra, Bundle extras, Throwable error) {
+ for (Listener listener : mListeners) {
+ listener.onError(type, extra, extras, error);
+ }
+ }
+
+ protected void pushOnStateChanged(int newState) {
+ for (Listener listener : mListeners) {
+ listener.onStateChanged(newState);
+ }
+ }
+
+ protected void pushOnBufferingUpdate(int percent) {
+ for (Listener listener : mListeners) {
+ listener.onBufferingUpdate(percent);
+ }
+ }
+
+ protected void pushOnFocusLost() {
+ for (Listener listener : mListeners) {
+ listener.onFocusLost();
+ }
+ }
+
+ protected void pushOnNextStarted() {
+ for (Listener listener : mListeners) {
+ listener.onNextStarted();
+ }
+ }
+
+ public interface Listener {
+ public static final int ERROR_LOAD_FAILED = 1770;
+ public static final int ERROR_PREPARE_ERROR = 1771;
+ public static final int ERROR_PLAYBACK_FAILED = 1772;
+
+ /**
+ * When an error occurs onError will be called but not onStateChanged.
+ * The Manager will remain in the error state until
+ * {@link #setContent()} is called again.
+ */
+ public void onError(int type, int extra, Bundle extras,
+ Throwable error);
+
+ /**
+ * onStateChanged will be called whenever the state of the manager
+ * transitions except to an error state.
+ */
+ public void onStateChanged(int newState);
+
+ /**
+ * This is a passthrough of
+ * {@link MediaPlayer.OnBufferingUpdateListener}.
+ */
+ public void onBufferingUpdate(int percent);
+
+ /**
+ * Called when audio focus is lost and it is not transient or ducking.
+ */
+ public void onFocusLost();
+
+ /**
+ * Called when the next item was started playing. Only called if a next
+ * item has been set and the current item has ended.
+ */
+ public void onNextStarted();
+ }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java b/tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java
new file mode 100644
index 0000000..f333fce
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java
@@ -0,0 +1,22 @@
+package com.android.onemedia.playback;
+
+import android.content.Context;
+import android.media.MediaRouter;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * TODO: Insert description here.
+ */
+public class RendererFactory {
+ private static final String TAG = "RendererFactory";
+
+ public Renderer createRenderer(MediaRouter.RouteInfo route, Context context, Bundle params) {
+ if (route.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_LOCAL) {
+ return new LocalRenderer(context, params);
+ }
+ Log.e(TAG, "Unable to create renderer for route of playback type "
+ + route.getPlaybackType());
+ return null;
+ }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java b/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java
new file mode 100644
index 0000000..9b50dad
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java
@@ -0,0 +1,53 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+import android.support.v7.media.MediaItemMetadata;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TODO: Insert description here. (generated by epastern)
+ */
+public class RequestUtils {
+ public static final String ACTION_SET_CONTENT = "set_content";
+ public static final String ACTION_SET_NEXT_CONTENT = "set_next_content";
+
+ public static final String EXTRA_KEY_SOURCE = "source";
+ public static final String EXTRA_KEY_METADATA = "metadata";
+ public static final String EXTRA_KEY_HEADERS = "headers";
+
+ private RequestUtils() {
+ }
+
+ public static class ContentBuilder {
+ private Bundle mBundle;
+
+ public ContentBuilder() {
+ mBundle = new Bundle();
+ }
+
+ public ContentBuilder setSource(String source) {
+ mBundle.putString(EXTRA_KEY_SOURCE, source);
+ return this;
+ }
+
+ /**
+ * @see MediaItemMetadata
+ * @param metadata The metadata for this item
+ */
+ public ContentBuilder setMetadata(Bundle metadata) {
+ mBundle.putBundle(EXTRA_KEY_METADATA, metadata);
+ return this;
+ }
+
+ public ContentBuilder setHeaders(HashMap<String, String> headers) {
+ mBundle.putSerializable(EXTRA_KEY_HEADERS, headers);
+ return this;
+ }
+
+ public Bundle build() {
+ return mBundle;
+ }
+ }
+}
diff --git a/tests/RenderThreadTest/Android.mk b/tests/RenderThreadTest/Android.mk
new file mode 100644
index 0000000..bdcba2e
--- /dev/null
+++ b/tests/RenderThreadTest/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := RenderThreadTest
+
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/RenderThreadTest/AndroidManifest.xml b/tests/RenderThreadTest/AndroidManifest.xml
new file mode 100644
index 0000000..c76cfce
--- /dev/null
+++ b/tests/RenderThreadTest/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.renderthread"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="18" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".SubActivity"
+ android:theme="@style/AppTheme.Transparent" />
+ </application>
+
+</manifest>
diff --git a/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
new file mode 100644
index 0000000..755232d
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
Binary files differ
diff --git a/tests/RenderThreadTest/res/layout/activity_main.xml b/tests/RenderThreadTest/res/layout/activity_main.xml
new file mode 100644
index 0000000..1fd5459
--- /dev/null
+++ b/tests/RenderThreadTest/res/layout/activity_main.xml
@@ -0,0 +1,12 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity" >
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:divider="@null" />
+
+</FrameLayout>
diff --git a/tests/RenderThreadTest/res/layout/activity_sub.xml b/tests/RenderThreadTest/res/layout/activity_sub.xml
new file mode 100644
index 0000000..713cee4
--- /dev/null
+++ b/tests/RenderThreadTest/res/layout/activity_sub.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <View
+ android:id="@+id/bg_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/starry_night_bg" />
+
+ <LinearLayout
+ android:id="@+id/my_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <View
+ android:id="@+id/from_left"
+ android:layout_width="match_parent"
+ android:layout_height="48dip"
+ android:background="#7000FF00" />
+
+ <View
+ android:id="@+id/from_right"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_margin="80dip"
+ android:layout_weight="1"
+ android:background="#90FF0000" />
+
+ <View
+ android:id="@+id/from_left"
+ android:layout_width="match_parent"
+ android:layout_height="48dip"
+ android:background="#7000FF00" />
+ </LinearLayout>
+
+</FrameLayout> \ No newline at end of file
diff --git a/tests/RenderThreadTest/res/layout/item_layout.xml b/tests/RenderThreadTest/res/layout/item_layout.xml
new file mode 100644
index 0000000..5bdb1ac
--- /dev/null
+++ b/tests/RenderThreadTest/res/layout/item_layout.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:background="#33b5e5"
+/> \ No newline at end of file
diff --git a/tests/RenderThreadTest/res/values/strings.xml b/tests/RenderThreadTest/res/values/strings.xml
new file mode 100644
index 0000000..f782e98
--- /dev/null
+++ b/tests/RenderThreadTest/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">Render Thread</string>
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Hello world!</string>
+
+</resources>
diff --git a/tests/RenderThreadTest/res/values/styles.xml b/tests/RenderThreadTest/res/values/styles.xml
new file mode 100644
index 0000000..f6b5d6a
--- /dev/null
+++ b/tests/RenderThreadTest/res/values/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="android:Theme.Holo.Light">
+ </style>
+
+ <style name="AppTheme.Transparent">
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ </style>
+
+</resources>
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
new file mode 100644
index 0000000..09531fd
--- /dev/null
+++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
@@ -0,0 +1,158 @@
+
+package com.example.renderthread;
+
+import android.animation.TimeInterpolator;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.view.RenderNode;
+import android.view.HardwareRenderer;
+import android.view.ThreadedRenderer;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MainActivity extends Activity implements OnItemClickListener {
+
+ static final int DURATION = 400;
+
+ static final String KEY_NAME = "name";
+ static final String KEY_CLASS = "clazz";
+
+ static Map<String,?> make(String name) {
+ Map<String,Object> ret = new HashMap<String,Object>();
+ ret.put(KEY_NAME, name);
+ return ret;
+ }
+
+ @SuppressWarnings("serial")
+ static final ArrayList<Map<String,?>> SAMPLES = new ArrayList<Map<String,?>>() {{
+ for (int i = 1; i < 25; i++) {
+ add(make("List Item: " + i));
+ }
+ }};
+
+ Handler mHandler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ HardwareRenderer.sUseRenderThread = true;
+ setContentView(R.layout.activity_main);
+ ListView lv = (ListView) findViewById(android.R.id.list);
+ lv.setDrawSelectorOnTop(true);
+ lv.setAdapter(new SimpleAdapter(this, SAMPLES,
+ R.layout.item_layout, new String[] { KEY_NAME },
+ new int[] { android.R.id.text1 }));
+ lv.setOnItemClickListener(this);
+ getActionBar().setTitle("MainActivity");
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ ListView lv = (ListView) findViewById(android.R.id.list);
+ for (int i = 0; i < lv.getChildCount(); i++) {
+ lv.getChildAt(i).animate().translationY(0).setDuration(DURATION);
+ }
+ }
+
+ private static class DisplayListAnimator {
+ private static final TimeInterpolator sDefaultInterpolator =
+ new AccelerateDecelerateInterpolator();
+
+ RenderNode mDisplayList;
+ float mFromValue;
+ float mDelta;
+ long mDuration = DURATION * 2;
+ long mStartTime;
+
+ DisplayListAnimator(View view, float translateXBy) {
+ mDelta = translateXBy;
+ mFromValue = view.getTranslationY();
+ mDisplayList = view.getDisplayList();
+ }
+
+ boolean animate(long currentTime) {
+ if (mStartTime == 0) mStartTime = currentTime;
+
+ float fraction = (float)(currentTime - mStartTime) / mDuration;
+ if (fraction > 1) {
+ return false;
+ }
+ fraction = sDefaultInterpolator.getInterpolation(fraction);
+ float translation = mFromValue + (mDelta * fraction);
+ mDisplayList.setTranslationY(translation);
+ return fraction < 1f;
+ }
+ }
+
+ private static class AnimationExecutor implements Runnable {
+ DisplayListAnimator[] mAnimations;
+ ThreadedRenderer mRenderer;
+
+ AnimationExecutor(ThreadedRenderer renderer, DisplayListAnimator[] animations) {
+ mRenderer = renderer;
+ mAnimations = animations;
+ ThreadedRenderer.postToRenderThread(this);
+ }
+
+ @Override
+ public void run() {
+ boolean hasMore = false;
+ long now = SystemClock.uptimeMillis();
+ for (DisplayListAnimator animator : mAnimations) {
+ hasMore |= animator.animate(now);
+ }
+ mRenderer.repeatLastDraw();
+ if (hasMore) {
+ ThreadedRenderer.postToRenderThread(this);
+ }
+ }
+
+ }
+
+ @Override
+ public void onItemClick(final AdapterView<?> adapterView, View clickedView,
+ int clickedPosition, long clickedId) {
+ int topPosition = adapterView.getFirstVisiblePosition();
+ int dy = adapterView.getHeight();
+ final DisplayListAnimator[] animators = new DisplayListAnimator[adapterView.getChildCount()];
+ for (int i = 0; i < adapterView.getChildCount(); i++) {
+ int pos = topPosition + i;
+ View child = adapterView.getChildAt(i);
+ float delta = (pos - clickedPosition) * 1.1f;
+ if (delta == 0) delta = -1;
+ animators[i] = new DisplayListAnimator(child, dy * delta);
+ }
+ adapterView.invalidate();
+ adapterView.post(new Runnable() {
+
+ @Override
+ public void run() {
+ new AnimationExecutor((ThreadedRenderer) adapterView.getHardwareRenderer(), animators);
+ }
+ });
+ //mHandler.postDelayed(mLaunchActivity, (long) (DURATION * .4));
+ mLaunchActivity.run();
+ }
+
+ private Runnable mLaunchActivity = new Runnable() {
+
+ @Override
+ public void run() {
+ startActivity(new Intent(MainActivity.this, SubActivity.class));
+ overridePendingTransition(0, 0);
+ }
+ };
+
+}
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java
new file mode 100644
index 0000000..892cbae
--- /dev/null
+++ b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.renderthread;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.SystemClock;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class SubActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ long before = SystemClock.currentThreadTimeMillis();
+ setContentView(R.layout.activity_sub);
+ getActionBar().setTitle("SubActivity");
+ // Simulate being a real app!
+ while (SystemClock.currentThreadTimeMillis() - before < 100) {
+ View v = new View(this, null);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ ViewGroup container = (ViewGroup) findViewById(R.id.my_container);
+ int dx = getWindowManager().getDefaultDisplay().getWidth();
+ for (int i = 0; i < container.getChildCount(); i++) {
+ View child = container.getChildAt(i);
+ int dir = child.getId() == R.id.from_left ? 1 : -1;
+ child.setTranslationX(dx * dir);
+ child.animate().translationX(0).setDuration(MainActivity.DURATION);
+ }
+ View bg = findViewById(R.id.bg_container);
+ bg.setAlpha(0f);
+ bg.animate().alpha(1f).setDuration(MainActivity.DURATION);
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ overridePendingTransition(0, 0);
+ }
+}
diff --git a/tests/SharedLibrary/client/Android.mk b/tests/SharedLibrary/client/Android.mk
index 60ef92a..1d66bb9 100644
--- a/tests/SharedLibrary/client/Android.mk
+++ b/tests/SharedLibrary/client/Android.mk
@@ -3,7 +3,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_APK_LIBRARIES := SharedLibrary
+LOCAL_RES_LIBRARIES := SharedLibrary
LOCAL_PACKAGE_NAME := SharedLibraryClient
diff --git a/tests/SharedLibrary/client/AndroidManifest.xml b/tests/SharedLibrary/client/AndroidManifest.xml
index c6a43c0..a39c754 100644
--- a/tests/SharedLibrary/client/AndroidManifest.xml
+++ b/tests/SharedLibrary/client/AndroidManifest.xml
@@ -16,7 +16,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.test.lib_client">
- <application android:label="@string/app_title">
+ <application android:label="@string/app_title" android:theme="@style/Theme">
<uses-library android:name="android.test.runner" />
<uses-library android:name="com.google.android.test.shared_library" />
<activity android:name="ActivityMain">
diff --git a/tests/SharedLibrary/client/res/layout/main.xml b/tests/SharedLibrary/client/res/layout/main.xml
new file mode 100644
index 0000000..067ef9f
--- /dev/null
+++ b/tests/SharedLibrary/client/res/layout/main.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView android:id="@+id/label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@com.google.android.test.shared_library:string/shared_string"
+ style="@com.google.android.test.shared_library:style/CodeFont"/>
+
+ <com.google.android.test.shared_library.AddressView
+ xmlns:custom="http://schemas.android.com/apk/res/com.google.android.test.shared_library"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ custom:name="Professor Android"
+ custom:streetNumber="44"
+ custom:streetName="KitKat Lane"
+ custom:city="AndroidVille"
+ custom:state="OS"
+ custom:country="Mobile"
+ custom:zip="12345"/>
+</LinearLayout>
diff --git a/tests/SharedLibrary/client/res/values/strings.xml b/tests/SharedLibrary/client/res/values/strings.xml
index 3757a25..d9efdc7 100644
--- a/tests/SharedLibrary/client/res/values/strings.xml
+++ b/tests/SharedLibrary/client/res/values/strings.xml
@@ -16,4 +16,5 @@
<resources>
<string name="app_title">SharedLibrary client</string>
+ <string name="changes">@com.google.android.test.shared_library:string/shared_string</string>
</resources>
diff --git a/tests/SharedLibrary/client/res/values/themes.xml b/tests/SharedLibrary/client/res/values/themes.xml
new file mode 100644
index 0000000..a14f98a
--- /dev/null
+++ b/tests/SharedLibrary/client/res/values/themes.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <style name="Theme" parent="com.google.android.test.shared_library:Theme">
+ </style>
+</resources>
diff --git a/tests/SharedLibrary/client/src/com/google/android/test/lib_client/ActivityMain.java b/tests/SharedLibrary/client/src/com/google/android/test/lib_client/ActivityMain.java
index d6121a5..7276b3c 100644
--- a/tests/SharedLibrary/client/src/com/google/android/test/lib_client/ActivityMain.java
+++ b/tests/SharedLibrary/client/src/com/google/android/test/lib_client/ActivityMain.java
@@ -18,18 +18,33 @@ package com.google.android.test.lib_client;
import android.app.Activity;
import android.os.Bundle;
-import android.widget.TextView;
import com.google.android.test.shared_library.SharedLibraryMain;
public class ActivityMain extends Activity {
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ String[] expectedAnimals = new String[] {
+ "Racoon",
+ "Rhino",
+ "Elephant"
+ };
+
+ String[] animals = getResources().getStringArray(com.google.android.test.shared_library.R.array.animals);
+ if (animals == null || animals.length != expectedAnimals.length) {
+ throw new AssertionError("Animal list from shared library is null or wrong length.");
+ }
- TextView content = new TextView(this);
- content.setText("Library version: " + SharedLibraryMain.getVersion(this) + "!");
+ for (int i = 0; i < expectedAnimals.length; i++) {
+ if (!expectedAnimals[i].equals(animals[i])) {
+ throw new AssertionError("Expected '" + expectedAnimals[i]
+ + "' at index " + i + " but got '" + animals[i]);
+ }
+ }
SharedLibraryMain.ensureVersion(this, SharedLibraryMain.VERSION_BASE);
- setContentView(content);
}
}
diff --git a/tests/SharedLibrary/lib/Android.mk b/tests/SharedLibrary/lib/Android.mk
index c19e23a..b2fc369 100644
--- a/tests/SharedLibrary/lib/Android.mk
+++ b/tests/SharedLibrary/lib/Android.mk
@@ -3,8 +3,13 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_AAPT_FLAGS := --shared-lib
LOCAL_PACKAGE_NAME := SharedLibrary
-LOCAL_MODULE_TAGS := tests
+LOCAL_EXPORT_PACKAGE_RESOURCES := true
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.proguard
include $(BUILD_PACKAGE)
diff --git a/tests/SharedLibrary/lib/proguard.proguard b/tests/SharedLibrary/lib/proguard.proguard
new file mode 100644
index 0000000..e5dfbe1
--- /dev/null
+++ b/tests/SharedLibrary/lib/proguard.proguard
@@ -0,0 +1,7 @@
+-keepparameternames
+-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
+ SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
+
+-keep public class * {
+ public protected *;
+}
diff --git a/tests/SharedLibrary/lib/res/layout/address.xml b/tests/SharedLibrary/lib/res/layout/address.xml
new file mode 100644
index 0000000..835f43e
--- /dev/null
+++ b/tests/SharedLibrary/lib/res/layout/address.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <TextView android:id="@+id/name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <TextView android:id="@+id/street"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <TextView android:id="@+id/cityStateZip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <TextView android:id="@+id/country"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+</merge>
diff --git a/tests/SharedLibrary/lib/res/values/attrs.xml b/tests/SharedLibrary/lib/res/values/attrs.xml
new file mode 100644
index 0000000..8cefe92
--- /dev/null
+++ b/tests/SharedLibrary/lib/res/values/attrs.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <declare-styleable name="AddressView">
+ <attr name="name" format="string" />
+ <attr name="streetNumber" format="integer" />
+ <attr name="streetName" format="string" />
+ <attr name="city" format="string" />
+ <attr name="state" format="string" />
+ <attr name="zip" format="string" />
+ <attr name="country" format="string" />
+ </declare-styleable>
+</resources>
diff --git a/tests/SharedLibrary/lib/res/values/public.xml b/tests/SharedLibrary/lib/res/values/public.xml
new file mode 100644
index 0000000..37b1ec9
--- /dev/null
+++ b/tests/SharedLibrary/lib/res/values/public.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <public type="string" name="shared_string" id="0x00020003" />
+ <public type="style" name="CodeFont" id="0x00040000" />
+ <public type="style" name="Theme" id="0x00040001" />
+
+ <public type="attr" name="name" id="0x00010000" />
+ <public type="attr" name="streetNumber" id="0x00010001" />
+ <public type="attr" name="streetName" id="0x00010002" />
+ <public type="attr" name="city" id="0x00010003" />
+ <public type="attr" name="state" id="0x00010004" />
+ <public type="attr" name="zip" id="0x00010005" />
+ <public type="attr" name="country" id="0x00010006" />
+
+ <public type="array" name="animals" id="0x02050000" />
+</resources>
diff --git a/tests/SharedLibrary/lib/res/values/strings.xml b/tests/SharedLibrary/lib/res/values/strings.xml
index bbfb0b4..6827f93 100644
--- a/tests/SharedLibrary/lib/res/values/strings.xml
+++ b/tests/SharedLibrary/lib/res/values/strings.xml
@@ -19,4 +19,13 @@
<string name="upgrade_body"><xliff:g id="app">%1$s</xliff:g> requires a newer version
of <xliff:g id="lib">%2$s</xliff:g> to run.</string>
<string name="upgrade_button">Upgrade</string>
+ <string name="shared_string">Shared string!</string>
+
+ <string-array name="animals">
+ <item>@string/racoon</item>
+ <item>Rhino</item>
+ <item>Elephant</item>
+ </string-array>
+
+ <string name="racoon">Racoon</string>
</resources>
diff --git a/tests/SharedLibrary/lib/res/values/themes.xml b/tests/SharedLibrary/lib/res/values/themes.xml
new file mode 100644
index 0000000..f1081ac
--- /dev/null
+++ b/tests/SharedLibrary/lib/res/values/themes.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <style name="CodeFont" parent="@android:style/TextAppearance.Medium">
+ <item name="android:textColor">#00FF00</item>
+ <item name="android:typeface">monospace</item>
+ </style>
+
+ <style name="Theme" parent="android:Theme.Holo.Light">
+ <item name="android:actionBarStyle">@style/ActionBar</item>
+ </style>
+
+ <style name="ActionBar" parent="android:Widget.Holo.Light.ActionBar.Solid.Inverse">
+ <item name="android:background">@color/orange</item>
+ </style>
+
+ <color name="orange">#f0ad4e</color>
+</resources>
diff --git a/tests/SharedLibrary/lib/src/com/google/android/test/shared_library/AddressView.java b/tests/SharedLibrary/lib/src/com/google/android/test/shared_library/AddressView.java
new file mode 100644
index 0000000..dcaf68c
--- /dev/null
+++ b/tests/SharedLibrary/lib/src/com/google/android/test/shared_library/AddressView.java
@@ -0,0 +1,44 @@
+package com.google.android.test.shared_library;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class AddressView extends LinearLayout {
+ private TextView mNameView;
+ private TextView mStreetView;
+ private TextView mCityStateZipView;
+ private TextView mCountryView;
+
+ public AddressView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setOrientation(VERTICAL);
+
+ View view = LayoutInflater.from(context).inflate(R.layout.address, this);
+ mNameView = (TextView) view.findViewById(R.id.name);
+ mStreetView = (TextView) view.findViewById(R.id.street);
+ mCityStateZipView = (TextView) view.findViewById(R.id.cityStateZip);
+ mCountryView = (TextView) view.findViewById(R.id.country);
+
+ TypedArray a = context.getTheme().obtainStyledAttributes(
+ attrs,
+ R.styleable.AddressView,
+ 0, 0);
+ try {
+ mNameView.setText(a.getString(R.styleable.AddressView_name));
+ int streetNumber = a.getInteger(R.styleable.AddressView_streetNumber, -1);
+ mStreetView.setText((streetNumber <= 0 ? "" : Integer.toString(streetNumber)) +
+ " " + a.getString(R.styleable.AddressView_streetName));
+ mCityStateZipView.setText(a.getString(R.styleable.AddressView_city) + ", " +
+ a.getString(R.styleable.AddressView_state) + " " +
+ a.getString(R.styleable.AddressView_zip));
+ mCountryView.setText(a.getString(R.styleable.AddressView_country));
+ } finally {
+ a.recycle();
+ }
+ }
+}
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index cceed16..3bd35a7 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -37,7 +37,7 @@ public class ActivityManagerPermissionTests extends TestCase {
}
@SmallTest
- public void testREORDER_TASKS() {
+ public void testREORDER_TASKS() {
try {
mAm.moveTaskToFront(0, 0, null);
fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
@@ -67,7 +67,7 @@ public class ActivityManagerPermissionTests extends TestCase {
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
- }
+ }
@SmallTest
public void testCHANGE_CONFIGURATION() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
index b690c45..93aa555 100644
--- a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
@@ -16,7 +16,7 @@
package com.android.framework.permission.tests;
-import junit.framework.TestCase;
+import android.app.PackageInstallObserver;
import android.content.pm.PackageManager;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -68,10 +68,14 @@ public class PmPermissionsTests extends AndroidTestCase {
* This test verifies that PackageManger.installPackage enforces permission
* android.permission.INSTALL_PACKAGES
*/
+ private class TestInstallObserver extends PackageInstallObserver {
+ }
+
@SmallTest
public void testInstallPackage() {
+ TestInstallObserver observer = new TestInstallObserver();
try {
- mPm.installPackage(null, null, 0, null);
+ mPm.installPackage(null, observer, 0, null);
fail("PackageManager.installPackage" +
"did not throw SecurityException as expected");
} catch (SecurityException e) {
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
index 4dfe0fe..322b853 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
@@ -32,7 +32,7 @@ import junit.framework.TestCase;
*/
public class ServiceManagerPermissionTests extends TestCase {
@SmallTest
- public void testAddService() {
+ public void testAddService() {
try {
// The security in the service manager is that you can't replace
// a service that is already published.
@@ -43,7 +43,7 @@ public class ServiceManagerPermissionTests extends TestCase {
} catch (SecurityException e) {
// expected
}
- }
+ }
@SmallTest
public void testSetPermissionController() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
index 90b6abc..b12ed94 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
@@ -18,6 +18,7 @@ package com.android.framework.permission.tests;
import junit.framework.TestCase;
+import android.media.AudioManager;
import android.os.Binder;
import android.os.IVibratorService;
import android.os.Process;
@@ -47,7 +48,8 @@ public class VibratorServicePermissionTest extends TestCase {
*/
public void testVibrate() throws RemoteException {
try {
- mVibratorService.vibrate(Process.myUid(), null, 2000, new Binder());
+ mVibratorService.vibrate(Process.myUid(), null, 2000, AudioManager.STREAM_ALARM,
+ new Binder());
fail("vibrate did not throw SecurityException as expected");
} catch (SecurityException e) {
// expected
@@ -63,7 +65,8 @@ public class VibratorServicePermissionTest extends TestCase {
*/
public void testVibratePattern() throws RemoteException {
try {
- mVibratorService.vibratePattern(Process.myUid(), null, new long[] {0}, 0, new Binder());
+ mVibratorService.vibratePattern(Process.myUid(), null, new long[] {0}, 0,
+ AudioManager.STREAM_ALARM, new Binder());
fail("vibratePattern did not throw SecurityException as expected");
} catch (SecurityException e) {
// expected
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index df32ee1..6f5788a 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -41,7 +41,7 @@ public class WindowManagerPermissionTests extends TestCase {
}
@SmallTest
- public void testMANAGE_APP_TOKENS() {
+ public void testMANAGE_APP_TOKENS() {
try {
mWm.pauseKeyDispatching(null);
fail("IWindowManager.pauseKeyDispatching did not throw SecurityException as"