diff options
author | Jim Miller <jaggies@google.com> | 2010-09-02 13:17:24 -0700 |
---|---|---|
committer | Jim Miller <jaggies@google.com> | 2010-09-02 17:06:39 -0700 |
commit | 5ce730797a8a7278dfe19dac8a9460b25675fed0 (patch) | |
tree | f7b506eeef5ccc496e206ea36609e201e189aedc /carousel/test | |
parent | 1fa3a8f74d46a616e27c23ed1512f4b7de2ad66d (diff) | |
download | android_frameworks_ex-5ce730797a8a7278dfe19dac8a9460b25675fed0.tar.gz android_frameworks_ex-5ce730797a8a7278dfe19dac8a9460b25675fed0.tar.bz2 android_frameworks_ex-5ce730797a8a7278dfe19dac8a9460b25675fed0.zip |
Add carousel as static library to build.
Change-Id: I5e3eb0a6c3ea6deeee3856c486bbb469c8d20360
Diffstat (limited to 'carousel/test')
32 files changed, 1063 insertions, 0 deletions
diff --git a/carousel/test/Android.mk b/carousel/test/Android.mk new file mode 100644 index 0000000..e00c83c --- /dev/null +++ b/carousel/test/Android.mk @@ -0,0 +1,29 @@ +# +# Copyright (C) 2009 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) \ + $(call all-renderscript-files-under, src) \ + ../../../../frameworks/ex/carousel/java/com/android/ex/carousel/carousel.rs + +LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel + +LOCAL_PACKAGE_NAME := CarouselWidgetTests +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) diff --git a/carousel/test/AndroidManifest.xml b/carousel/test/AndroidManifest.xml new file mode 100644 index 0000000..78b819d --- /dev/null +++ b/carousel/test/AndroidManifest.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2009 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.carouseltest"> + + <uses-permission android:name="android.permission.GET_TASKS" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + + <application> + + <activity + android:name="MusicDemoActivity" + android:label="@string/music_demo_activity_label" + android:theme="@android:style/Theme.NoTitleBar" + android:configChanges="orientation"> + + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + + </activity> + + <activity + android:name="CarouselTestActivity" + android:label="@string/carousel_test_activity_label" + android:theme="@android:style/Theme.NoTitleBar" + android:configChanges="orientation"> + + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + + </activity> + + <activity + android:name="TaskSwitcherActivity" + android:label="@string/task_switcher_activity_label" + android:theme="@android:style/Theme.NoTitleBar" + android:configChanges="orientation"> + + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + + </activity> + + </application> +</manifest> diff --git a/carousel/test/res/anim/zoom_enter.xml b/carousel/test/res/anim/zoom_enter.xml new file mode 100644 index 0000000..f037208 --- /dev/null +++ b/carousel/test/res/anim/zoom_enter.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2009, 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. +*/ +--> + +<!-- Special window zoom animation: this is the element that enters the screen, + it starts at 200% and scales down. Goes with zoom_exit.xml. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:anim/decelerate_interpolator"> + <scale android:fromXScale="0.0" android:toXScale="1.0" + android:fromYScale="0.0" android:toYScale="1.0" + android:pivotX="50%p" android:pivotY="50%p" + android:duration="500" /> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="500"/> +</set> diff --git a/carousel/test/res/anim/zoom_exit.xml b/carousel/test/res/anim/zoom_exit.xml new file mode 100644 index 0000000..207f570 --- /dev/null +++ b/carousel/test/res/anim/zoom_exit.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2009, 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. +*/ +--> + +<!-- Special window zoom animation: this is the element that exits the + screen, it is forced above the entering element and starts at its + normal size (filling the screen) and scales down while fading out. + This goes with zoom_enter.xml. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:anim/decelerate_interpolator" + android:zAdjustment="top"> + <scale android:fromXScale="1.0" android:toXScale="4.0" + android:fromYScale="1.0" android:toYScale="4.0" + android:pivotX="50%p" android:pivotY="50%p" + android:duration="500" /> + <alpha android:fromAlpha="1.0" android:toAlpha="0" + android:duration="500"/> +</set> diff --git a/carousel/test/res/drawable/blank_album.png b/carousel/test/res/drawable/blank_album.png Binary files differnew file mode 100644 index 0000000..76331d5 --- /dev/null +++ b/carousel/test/res/drawable/blank_album.png diff --git a/carousel/test/res/drawable/emo_im_angel.png b/carousel/test/res/drawable/emo_im_angel.png Binary files differnew file mode 100644 index 0000000..10742a6 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_angel.png diff --git a/carousel/test/res/drawable/emo_im_cool.png b/carousel/test/res/drawable/emo_im_cool.png Binary files differnew file mode 100644 index 0000000..e3c8654 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_cool.png diff --git a/carousel/test/res/drawable/emo_im_crying.png b/carousel/test/res/drawable/emo_im_crying.png Binary files differnew file mode 100644 index 0000000..b23791c --- /dev/null +++ b/carousel/test/res/drawable/emo_im_crying.png diff --git a/carousel/test/res/drawable/emo_im_foot_in_mouth.png b/carousel/test/res/drawable/emo_im_foot_in_mouth.png Binary files differnew file mode 100644 index 0000000..050b7be --- /dev/null +++ b/carousel/test/res/drawable/emo_im_foot_in_mouth.png diff --git a/carousel/test/res/drawable/emo_im_happy.png b/carousel/test/res/drawable/emo_im_happy.png Binary files differnew file mode 100644 index 0000000..69e3bed --- /dev/null +++ b/carousel/test/res/drawable/emo_im_happy.png diff --git a/carousel/test/res/drawable/emo_im_kissing.png b/carousel/test/res/drawable/emo_im_kissing.png Binary files differnew file mode 100644 index 0000000..0cca68e --- /dev/null +++ b/carousel/test/res/drawable/emo_im_kissing.png diff --git a/carousel/test/res/drawable/emo_im_laughing.png b/carousel/test/res/drawable/emo_im_laughing.png Binary files differnew file mode 100644 index 0000000..8406ad0 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_laughing.png diff --git a/carousel/test/res/drawable/emo_im_lips_are_sealed.png b/carousel/test/res/drawable/emo_im_lips_are_sealed.png Binary files differnew file mode 100644 index 0000000..222f175 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_lips_are_sealed.png diff --git a/carousel/test/res/drawable/emo_im_money_mouth.png b/carousel/test/res/drawable/emo_im_money_mouth.png Binary files differnew file mode 100644 index 0000000..d711bfb --- /dev/null +++ b/carousel/test/res/drawable/emo_im_money_mouth.png diff --git a/carousel/test/res/drawable/emo_im_sad.png b/carousel/test/res/drawable/emo_im_sad.png Binary files differnew file mode 100644 index 0000000..40017f1 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_sad.png diff --git a/carousel/test/res/drawable/emo_im_surprised.png b/carousel/test/res/drawable/emo_im_surprised.png Binary files differnew file mode 100644 index 0000000..4b2af7a --- /dev/null +++ b/carousel/test/res/drawable/emo_im_surprised.png diff --git a/carousel/test/res/drawable/emo_im_tongue_sticking_out.png b/carousel/test/res/drawable/emo_im_tongue_sticking_out.png Binary files differnew file mode 100644 index 0000000..42ac80d --- /dev/null +++ b/carousel/test/res/drawable/emo_im_tongue_sticking_out.png diff --git a/carousel/test/res/drawable/emo_im_undecided.png b/carousel/test/res/drawable/emo_im_undecided.png Binary files differnew file mode 100644 index 0000000..2cf5bd2 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_undecided.png diff --git a/carousel/test/res/drawable/emo_im_winking.png b/carousel/test/res/drawable/emo_im_winking.png Binary files differnew file mode 100644 index 0000000..a3a0876 --- /dev/null +++ b/carousel/test/res/drawable/emo_im_winking.png diff --git a/carousel/test/res/drawable/emo_im_wtf.png b/carousel/test/res/drawable/emo_im_wtf.png Binary files differnew file mode 100644 index 0000000..86c4bda --- /dev/null +++ b/carousel/test/res/drawable/emo_im_wtf.png diff --git a/carousel/test/res/drawable/emo_im_yelling.png b/carousel/test/res/drawable/emo_im_yelling.png Binary files differnew file mode 100644 index 0000000..cfd991a --- /dev/null +++ b/carousel/test/res/drawable/emo_im_yelling.png diff --git a/carousel/test/res/drawable/specularmap.png b/carousel/test/res/drawable/specularmap.png Binary files differnew file mode 100644 index 0000000..6b1c0d9 --- /dev/null +++ b/carousel/test/res/drawable/specularmap.png diff --git a/carousel/test/res/drawable/unknown.png b/carousel/test/res/drawable/unknown.png Binary files differnew file mode 100644 index 0000000..74bead5 --- /dev/null +++ b/carousel/test/res/drawable/unknown.png diff --git a/carousel/test/res/drawable/wait.png b/carousel/test/res/drawable/wait.png Binary files differnew file mode 100644 index 0000000..e3f892f --- /dev/null +++ b/carousel/test/res/drawable/wait.png diff --git a/carousel/test/res/layout/music_demo.xml b/carousel/test/res/layout/music_demo.xml new file mode 100644 index 0000000..ba3e628 --- /dev/null +++ b/carousel/test/res/layout/music_demo.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** 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. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <com.android.carouseltest.MyCarouselView + android:id="@+id/carousel" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1"> + </com.android.carouseltest.MyCarouselView>> + +</LinearLayout> diff --git a/carousel/test/res/layout/taskswitcher.xml b/carousel/test/res/layout/taskswitcher.xml new file mode 100644 index 0000000..2d07d54 --- /dev/null +++ b/carousel/test/res/layout/taskswitcher.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** 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. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <!-- Title --> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#80FFFFFF" + android:textStyle="bold" + android:singleLine="true" + android:text="@string/recent_tasks_title" + android:visibility="gone"/> + + <!-- This is only intended to be visible when carousel is invisible --> + <TextView + android:id="@+id/no_applications_message" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:textAppearance="?android:attr/textAppearanceSmall" + android:text="@string/no_recent_tasks" + android:visibility="gone"/> + + <com.android.carouseltest.MyCarouselView + android:id="@+id/carousel" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1"> + </com.android.carouseltest.MyCarouselView>> + +</LinearLayout> diff --git a/carousel/test/res/raw/book.a3d b/carousel/test/res/raw/book.a3d Binary files differnew file mode 100644 index 0000000..c38cc44 --- /dev/null +++ b/carousel/test/res/raw/book.a3d diff --git a/carousel/test/res/values/strings.xml b/carousel/test/res/values/strings.xml new file mode 100644 index 0000000..a64a04c --- /dev/null +++ b/carousel/test/res/values/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +* Copyright (C) 2009 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- General --><skip /> + <string name="music_demo_activity_label">MusicCarousel2</string> + <string name="carousel_test_activity_label">CarouselTest2</string> + <string name="task_switcher_activity_label">TaskSwitcher2</string> + + <string name="recent_tasks_title">Recent Applications</string> + <string name="no_recent_tasks">No recent tasks</string> + +</resources> diff --git a/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java b/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java new file mode 100644 index 0000000..f67ce77 --- /dev/null +++ b/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java @@ -0,0 +1,183 @@ +/* + * 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.carouseltest; + +import com.android.carouseltest.MyCarouselView; +import com.android.ex.carousel.CarouselView; +import com.android.ex.carousel.CarouselRS.CarouselCallback; + +import android.app.Activity; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.drawable.BitmapDrawable; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Message; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; + +public class CarouselTestActivity extends Activity { + private static final int HOLDOFF_DELAY = 0; + private static final int CARD_SLOTS = 56; + private static final int TOTAL_CARDS = 1000; + private static final int TEXTURE_HEIGHT = 255; + private static final int TEXTURE_WIDTH = 255; + private static final String TAG = "CarouselTestActivity"; + + private static final int SLOTS_VISIBLE = 7; + protected static final boolean DBG = true; + protected static final int SET_TEXTURE_N = 1000; + private CarouselView mView; + private Paint mPaint = new Paint(); + + private HandlerThread mTextureThread; + private HandlerThread mGeometryThread; + private Handler mTextureHandler; + private Handler mGeometryHandler; + private Handler mSetTextureHandler; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mView = new MyCarouselView(this); + mPaint.setColor(0xffffffff); + final Resources res = getResources(); + + mTextureThread = new HandlerThread(TAG); + mGeometryThread = new HandlerThread(TAG); + mTextureThread.start(); + mGeometryThread.start(); + + mTextureHandler = new Handler(mTextureThread.getLooper()) { + @Override + public void handleMessage(Message msg) { + if (msg.what < TOTAL_CARDS) { + final int id = (Integer) msg.arg1; + final int n = msg.what; + final Bitmap bitmap = createBitmap(id); + mSetTextureHandler.obtainMessage(SET_TEXTURE_N + n, bitmap).sendToTarget(); + } + } + }; + + mGeometryHandler = new Handler(mGeometryThread.getLooper()) { + @Override + public void handleMessage(Message msg) { + // TODO + } + }; + + mSetTextureHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (msg.what >= SET_TEXTURE_N) { + final Bitmap bitmap = (Bitmap) msg.obj; + mView.setTextureForItem(msg.what - SET_TEXTURE_N, bitmap); + } + } + }; + + mView.setCallback(mCarouselCallback); + mView.setSlotCount(CARD_SLOTS); + mView.createCards(TOTAL_CARDS); + mView.setVisibleSlots(SLOTS_VISIBLE); + mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS)); + mView.setDefaultBitmap(BitmapFactory.decodeResource(res, R.drawable.unknown)); + mView.setLoadingBitmap(BitmapFactory.decodeResource(res, R.drawable.wait)); + + /* + int flags = WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + mView.getWidth(), mView.getHeight(), WindowManager.LayoutParams.TYPE_APPLICATION, + flags, PixelFormat.TRANSLUCENT); + mView.setBackgroundColor(0x80000000); + + getWindow().setAttributes(lp); + */ + setContentView(mView); + } + + @Override + protected void onResume() { + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mView.onPause(); + } + + Bitmap createBitmap(int n) { + Bitmap bitmap = Bitmap.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT, + Bitmap.Config.RGB_565); + Canvas canvas = new Canvas(bitmap); + canvas.drawARGB(255, 64, 64, 64); + mPaint.setTextSize(100.0f); + canvas.drawText(""+n, 0, TEXTURE_HEIGHT-10, mPaint); + return bitmap; + } + + private CarouselCallback mCarouselCallback = new CarouselCallback() { + + public void onRequestTexture(int n) { + if (DBG) Log.v(TAG, "onRequestTexture(" + n + ")" ); + mTextureHandler.removeMessages(n); + Message message = mTextureHandler.obtainMessage(n, n, 0); + mTextureHandler.sendMessageDelayed(message, HOLDOFF_DELAY); + } + + public void onInvalidateTexture(final int n) { + if (DBG) Log.v(TAG, "onInvalidateTexture(" + n + ")"); + mTextureHandler.removeMessages(n); + } + + public void onRequestGeometry(int n) { + if (DBG) Log.v(TAG, "onRequestGeometry(" + n + ")"); + mGeometryHandler.removeMessages(n); + mGeometryHandler.sendMessage(mGeometryHandler.obtainMessage(n)); + } + + public void onInvalidateGeometry(int n) { + if (DBG) Log.v(TAG, "onInvalidateGeometry(" + n + ")"); + mGeometryHandler.removeMessages(n); + } + + public void onCardSelected(int n) { + if (DBG) Log.v(TAG, "onCardSelected(" + n + ")"); + } + + public void onAnimationStarted() { + + } + + public void onAnimationFinished() { + + } + + }; + +} diff --git a/carousel/test/src/com/android/carouseltest/MusicDemoActivity.java b/carousel/test/src/com/android/carouseltest/MusicDemoActivity.java new file mode 100644 index 0000000..e5f3504 --- /dev/null +++ b/carousel/test/src/com/android/carouseltest/MusicDemoActivity.java @@ -0,0 +1,248 @@ +/* + * 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.carouseltest; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; + +import com.android.carouseltest.MyCarouselView; +import com.android.ex.carousel.CarouselView; +import com.android.ex.carousel.CarouselRS.CarouselCallback; + +import android.app.Activity; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PaintFlagsDrawFilter; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Xfermode; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Message; +import android.renderscript.Mesh; +import android.util.Log; + +public class MusicDemoActivity extends Activity { + private static final int HOLDOFF_DELAY = 0; // larger # gives smoother animation but lag + private static final int CD_GEOMETRY = R.raw.book; + private static final int VISIBLE_SLOTS = 7; + private static final int CARD_SLOTS = 56; + private static final int TOTAL_CARDS = 10000; + private static final String TAG = "MusicDemoActivity"; + protected static final boolean DBG = true; + private static final boolean TEST_ON_DEMAND_GEOMETRY = false; // for testing.. geometry per card + protected static final int SET_TEXTURE_N = 1000; + private CarouselView mView; + private int imageResources[] = { + R.drawable.emo_im_angel, + R.drawable.emo_im_cool, + R.drawable.emo_im_crying, + R.drawable.emo_im_foot_in_mouth, + R.drawable.emo_im_happy, + R.drawable.emo_im_kissing, + R.drawable.emo_im_laughing, + R.drawable.emo_im_lips_are_sealed, + R.drawable.emo_im_money_mouth, + R.drawable.emo_im_sad, + R.drawable.emo_im_surprised, + R.drawable.emo_im_tongue_sticking_out, + R.drawable.emo_im_undecided, + R.drawable.emo_im_winking, + R.drawable.emo_im_wtf, + R.drawable.emo_im_yelling + }; + private Bitmap mSpecularMap; + private Mesh mGeometry; + + private HandlerThread mTextureThread; + private HandlerThread mGeometryThread; + private Handler mTextureHandler; + private Handler mGeometryHandler; + private Handler mSetTextureHandler; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mTextureThread = new HandlerThread(TAG); + mGeometryThread = new HandlerThread(TAG); + mTextureThread.start(); + mGeometryThread.start(); + + mTextureHandler = new Handler(mTextureThread.getLooper()) { + @Override + public void handleMessage(Message msg) { + if (msg.what < TOTAL_CARDS) { + final int resId = (Integer) msg.arg1; + final int n = msg.what; + final Bitmap bitmap = compositeBitmap(resId); + mSetTextureHandler.obtainMessage(SET_TEXTURE_N + n, bitmap).sendToTarget(); + } + } + }; + + mGeometryHandler = new Handler(mGeometryThread.getLooper()) { + @Override + public void handleMessage(Message msg) { + // TODO + } + }; + + mSetTextureHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (msg.what >= SET_TEXTURE_N) { + final Bitmap bitmap = (Bitmap) msg.obj; + mView.setTextureForItem(msg.what - SET_TEXTURE_N, bitmap); + } + } + }; + + final Resources res = getResources(); + setContentView(R.layout.music_demo); + // mView = new MyCarouselView(this); + mView = (CarouselView) findViewById(R.id.carousel); + mView.setCallback(mCallback); + mView.setSlotCount(CARD_SLOTS); + mView.createCards(TOTAL_CARDS); + mView.setVisibleSlots(VISIBLE_SLOTS); + mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS)); + mView.setDefaultBitmap(BitmapFactory.decodeResource(res, R.drawable.wait)); + mView.setLoadingBitmap(BitmapFactory.decodeResource(res, R.drawable.blank_album)); + mView.setDefaultGeometry(mView.loadGeometry(CD_GEOMETRY)); + } + + @Override + protected void onResume() { + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mView.onPause(); + } + + void writeBitmapToFile(Bitmap bitmap, String fname) { + File path = Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_PICTURES); + File file = new File(path, fname); + + try { + path.mkdirs(); + OutputStream os = new FileOutputStream(file); + MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null, + new MediaScannerConnection.OnScanCompletedListener() { + + public void onScanCompleted(String path, Uri uri) { + + } + }); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); + } catch (IOException e) { + Log.w("ExternalStorage", "Error writing " + file, e); + } + } + + private Bitmap compositeBitmap(int id) { + final Resources res = getResources(); + if (mSpecularMap == null) { + mSpecularMap = BitmapFactory.decodeResource(res, R.drawable.specularmap); + } + + final int width = mSpecularMap.getWidth(); + final int height = mSpecularMap.getHeight(); + + Log.v(TAG, "Width = " + width + ", height = " + height); + + final Bitmap artwork = BitmapFactory.decodeResource(res, id); + + /* + final Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + //result.setHasAlpha(false); + final Canvas canvas = new Canvas(result); + canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, + Paint.FILTER_BITMAP_FLAG)); + + Paint paint = new Paint(); + paint.setFilterBitmap(false); + + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); + canvas.drawBitmap(artwork, 0, 0, paint); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); + canvas.drawBitmap(mSpecularMap, 0, 0, paint); + + writeBitmapToFile(result, "test" + id + ".png"); + */ + + return artwork; + } + + private CarouselCallback mCallback = new CarouselCallback() { + + public void onRequestTexture(int n) { + if (DBG) Log.v(TAG, "onRequestTexture(" + n + ")" ); + mTextureHandler.removeMessages(n); + int resId = imageResources[n%imageResources.length]; + Message message = mTextureHandler.obtainMessage(n, resId, 0); + mTextureHandler.sendMessageDelayed(message, HOLDOFF_DELAY); + } + + public void onInvalidateTexture(final int n) { + if (DBG) Log.v(TAG, "onInvalidateTexture(" + n + ")"); + mTextureHandler.removeMessages(n); + } + + public void onRequestGeometry(int n) { + if (DBG) Log.v(TAG, "onRequestGeometry(" + n + ")"); + mGeometryHandler.removeMessages(n); + mGeometryHandler.sendMessage(mGeometryHandler.obtainMessage(n)); + } + + public void onInvalidateGeometry(int n) { + if (DBG) Log.v(TAG, "onInvalidateGeometry(" + n + ")"); + mGeometryHandler.removeMessages(n); + } + + public void onCardSelected(int n) { + if (DBG) Log.v(TAG, "onCardSelected(" + n + ")"); + } + + public void onAnimationStarted() { + + } + + public void onAnimationFinished() { + + } + + }; + +} diff --git a/carousel/test/src/com/android/carouseltest/MyCarouselView.java b/carousel/test/src/com/android/carouseltest/MyCarouselView.java new file mode 100644 index 0000000..b9ee6b1 --- /dev/null +++ b/carousel/test/src/com/android/carouseltest/MyCarouselView.java @@ -0,0 +1,39 @@ +/* + * 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.carouseltest; + +import android.content.Context; +import android.util.AttributeSet; + +import com.android.ex.carousel.CarouselView; +import com.android.ex.carousel.CarouselView.Info; + +public class MyCarouselView extends CarouselView { + + public MyCarouselView(Context context) { + this(context, null); + } + + public MyCarouselView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public Info getRenderScriptInfo() { + return new Info(R.raw.carousel); + } + +} diff --git a/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java b/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java new file mode 100644 index 0000000..7a2f047 --- /dev/null +++ b/carousel/test/src/com/android/carouseltest/TaskSwitcherActivity.java @@ -0,0 +1,315 @@ +/* + * 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.carouseltest; + +import java.util.ArrayList; +import java.util.List; +import com.android.carouseltest.R; + +import com.android.ex.carousel.CarouselRS.CarouselCallback; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.IThumbnailReceiver; +import android.app.ActivityManager.RunningTaskInfo; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.graphics.Bitmap.Config; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.RemoteException; +import android.util.Log; +import android.view.View; + +public class TaskSwitcherActivity extends Activity { + private static final String TAG = "TaskSwitcherActivity"; + private static final int CARD_SLOTS = 56; + private static final int MAX_TASKS = 20; + private static final int VISIBLE_SLOTS = 7; + private ActivityManager mActivityManager; + private List<RunningTaskInfo> mRunningTaskList; + private boolean mPortraitMode = true; + private ArrayList<ActivityDescription> mActivityDescriptions + = new ArrayList<ActivityDescription>(); + private MyCarouselView mView; + private Bitmap mBlankBitmap = Bitmap.createBitmap(128, 128, Config.RGB_565); + + static class ActivityDescription { + int id; + Bitmap thumbnail; + Drawable icon; + String label; + String description; + Intent intent; + Matrix matrix; + + public ActivityDescription(Bitmap _thumbnail, + Drawable _icon, String _label, String _desc, int _id) + { + thumbnail = _thumbnail; + icon = _icon; + label = _label; + description = _desc; + id = _id; + } + + public void clear() { + icon = null; + thumbnail = null; + label = null; + description = null; + intent = null; + matrix = null; + id = -1; + } + }; + + private ActivityDescription findActivityDescription(int id) { + for (int i = 0; i < mActivityDescriptions.size(); i++) { + ActivityDescription item = mActivityDescriptions.get(i); + if (item != null && item.id == id) { + return item; + } + } + return null; + } + + final CarouselCallback mCarouselCallback = new CarouselCallback() { + + public void onAnimationFinished() { + + } + + public void onAnimationStarted() { + + } + + public void onCardSelected(int n) { + if (n < mActivityDescriptions.size()) { + ActivityDescription item = mActivityDescriptions.get(n); + // prepare a launch intent and send it + if (item.intent != null) { + item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); + try { + Log.v(TAG, "Starting intent " + item.intent); + startActivity(item.intent); + overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit); + } catch (ActivityNotFoundException e) { + Log.w("Recent", "Unable to launch recent task", e); + } + finish(); + } + } + } + + public void onInvalidateTexture(int n) { + + } + + public void onRequestGeometry(int n) { + + } + + public void onInvalidateGeometry(int n) { + + } + + public void onRequestTexture(final int n) { + Log.v(TAG, "onRequestTexture(" + n + ")"); + if (n < mActivityDescriptions.size()) { + mView.post(new Runnable() { + public void run() { + ActivityDescription desc = mActivityDescriptions.get(n); + if (desc != null) { + Log.v(TAG, "FOUND ACTIVITY THUMBNAIL " + desc.thumbnail); + Bitmap bitmap = desc.thumbnail == null ? mBlankBitmap : desc.thumbnail; + mView.setTextureForItem(n, bitmap); + } else { + Log.v(TAG, "FAILED TO GET ACTIVITY THUMBNAIL FOR ITEM " + n); + } + } + }); + } + } + }; + + private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() { + + public void finished() throws RemoteException { + + } + + public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description) + throws RemoteException { + int w = bitmap.getWidth(); + int h = bitmap.getHeight(); + Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h + + " description '" + description + "'"); + ActivityDescription info = findActivityDescription(id); + if (info != null) { + info.thumbnail = bitmap; + final int thumbWidth = bitmap.getWidth(); + final int thumbHeight = bitmap.getHeight(); + if ((mPortraitMode && thumbWidth > thumbHeight) + || (!mPortraitMode && thumbWidth < thumbHeight)) { + Matrix matrix = new Matrix(); + matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); + info.matrix = matrix; + } else { + info.matrix = null; + } + } else { + Log.v(TAG, "Can't find view for id " + id); + } + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final Resources res = getResources(); + final View decorView = getWindow().getDecorView(); + + mView = new MyCarouselView(this); + mView.setSlotCount(CARD_SLOTS); + mView.setVisibleSlots(VISIBLE_SLOTS); + mView.createCards(1); + mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS)); + mView.setDefaultBitmap(BitmapFactory.decodeResource(res, R.drawable.wait)); + mView.setLoadingBitmap(BitmapFactory.decodeResource(res, R.drawable.wait)); + mView.setCallback(mCarouselCallback); + + mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + mPortraitMode = decorView.getHeight() > decorView.getWidth(); + + refresh(); + + setContentView(mView); + } + + @Override + protected void onResume() { + super.onResume(); + refresh(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT; + Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode); + refresh(); + } + + void updateRunningTasks() { + mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS + 2, 0, mThumbnailReceiver); + Log.v(TAG, "Portrait: " + mPortraitMode); + for (RunningTaskInfo r : mRunningTaskList) { + if (r.thumbnail != null) { + int thumbWidth = r.thumbnail.getWidth(); + int thumbHeight = r.thumbnail.getHeight(); + Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight); + ActivityDescription desc = findActivityDescription(r.id); + if (desc != null) { + desc.thumbnail = r.thumbnail; + desc.label = r.topActivity.flattenToShortString(); + if ((mPortraitMode && thumbWidth > thumbHeight) + || (!mPortraitMode && thumbWidth < thumbHeight)) { + Matrix matrix = new Matrix(); + matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); + desc.matrix = matrix; + } + } else { + Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id); + } + } else { + Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***"); + } + } + // HACK refresh carousel + mView.createCards(mActivityDescriptions.size()); + } + + private void updateRecentTasks() { + final PackageManager pm = getPackageManager(); + final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + + final List<ActivityManager.RecentTaskInfo> recentTasks = + am.getRecentTasks(MAX_TASKS + 2, ActivityManager.RECENT_IGNORE_UNAVAILABLE); + + ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME) + .resolveActivityInfo(pm, 0); + + //IconUtilities iconUtilities = new IconUtilities(this); + + int numTasks = recentTasks.size(); + mActivityDescriptions.clear(); + for (int i = 1, index = 0; i < numTasks && (index < MAX_TASKS + 2); ++i) { + final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i); + + Intent intent = new Intent(recentInfo.baseIntent); + if (recentInfo.origActivity != null) { + intent.setComponent(recentInfo.origActivity); + } + + // Skip the current home activity. + if (homeInfo != null + && homeInfo.packageName.equals(intent.getComponent().getPackageName()) + && homeInfo.name.equals(intent.getComponent().getClassName())) { + continue; + } + + intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) + | Intent.FLAG_ACTIVITY_NEW_TASK); + final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); + if (resolveInfo != null) { + final ActivityInfo info = resolveInfo.activityInfo; + final String title = info.loadLabel(pm).toString(); + Drawable icon = info.loadIcon(pm); + + int id = recentTasks.get(i).id; + if (id != -1 && title != null && title.length() > 0 && icon != null) { + //icon = iconUtilities.createIconDrawable(icon); + ActivityDescription item = new ActivityDescription(null, icon, title, null, id); + item.intent = intent; + mActivityDescriptions.add(item); + Log.v(TAG, "Added item[" + index + "], id=" + item.id); + ++index; + } else { + Log.v(TAG, "SKIPPING item " + id); + } + } + } + } + + private void refresh() { + updateRecentTasks(); + updateRunningTasks(); + mView.createCards(mActivityDescriptions.size()); + } +} |