summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authord34d <clark@cyngn.com>2016-01-25 18:23:43 -0800
committerd34d <clark@cyngn.com>2016-02-01 09:22:05 -0800
commit06c485f26820d02028eb618e5f592ffd1d2b55d0 (patch)
treee1f3e9895e092e143243179f4b81beefb9b8326c
parentdd650a0c66cfa2b9ef87be57d3d7347cfff648c1 (diff)
downloadandroid_packages_screensavers_Basic-06c485f26820d02028eb618e5f592ffd1d2b55d0.tar.gz
android_packages_screensavers_Basic-06c485f26820d02028eb618e5f592ffd1d2b55d0.tar.bz2
android_packages_screensavers_Basic-06c485f26820d02028eb618e5f592ffd1d2b55d0.zip
Create a live lock screen for Colors
Just a quick example of turning a Dream into a Live Lock Screen ;) Change-Id: Ib472037fc439db9b88bafd27d07c5aef2dd58ed6
-rw-r--r--Android.mk3
-rw-r--r--AndroidManifest.xml12
-rw-r--r--src/com/android/dreams/basic/ColorsGLRenderer.java26
-rw-r--r--src/com/android/dreams/basic/ColorsLockScreen.java184
4 files changed, 222 insertions, 3 deletions
diff --git a/Android.mk b/Android.mk
index aede576..f69b83a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,6 +6,9 @@ LOCAL_MODULE_TAGS := optional
# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ org.cyanogenmod.platform.sdk
+
LOCAL_PACKAGE_NAME := BasicDreams
# need tasty bits
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bb76649..9c63549 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3,6 +3,8 @@
package="com.android.dreams.basic"
>
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
+ <!-- Permission required for third party keyguard -->
+ <uses-permission android:name="android.permission.THIRD_PARTY_KEYGUARD" />
<application android:label="@string/app_name">
<service
android:name="Colors"
@@ -15,5 +17,15 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
+
+ <service
+ android:name="ColorsLockScreen"
+ android:exported="true"
+ android:icon="@mipmap/colors_icon"
+ android:label="@string/color_dream_name">
+ <intent-filter>
+ <action android:name="cyanogenmod.externalviews.KeyguardExternalViewProviderService" />
+ </intent-filter>
+ </service>
</application>
</manifest>
diff --git a/src/com/android/dreams/basic/ColorsGLRenderer.java b/src/com/android/dreams/basic/ColorsGLRenderer.java
index 91e4432..8ef1399 100644
--- a/src/com/android/dreams/basic/ColorsGLRenderer.java
+++ b/src/com/android/dreams/basic/ColorsGLRenderer.java
@@ -54,6 +54,8 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
Log.v(TAG, String.format(fmt, args));
}
+ private static final float DEFAULT_PERIOD = 1 / 4000f;
+
private final SurfaceTexture mSurface;
private int mWidth;
private int mHeight;
@@ -63,6 +65,7 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
private Square mSquare;
private long mLastFrameTime;
private int mFrameNum = 0;
+ private float mPeriod;
// It's so easy to use OpenGLES 2.0!
private EGL10 mEgl;
@@ -71,16 +74,21 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
private EGLSurface mEglSurface;
public ColorsGLRenderer(SurfaceTexture surface, int width, int height) {
+ this(surface, width, height, DEFAULT_PERIOD);
+ }
+
+ public ColorsGLRenderer(SurfaceTexture surface, int width, int height, float period) {
mSurface = surface;
mWidth = width;
mHeight = height;
+ mPeriod = period;
mChoreographer = Choreographer.getInstance();
}
public void start() {
initGL();
- mSquare = new Square();
+ mSquare = new Square(mPeriod);
mFrameNum = 0;
mChoreographer.postFrameCallback(this);
@@ -93,6 +101,15 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
finishGL();
}
+ public void pause() {
+ mChoreographer.removeFrameCallback(this);
+ }
+
+ public void resume() {
+ mChoreographer.removeFrameCallback(this);
+ mChoreographer.postFrameCallback(this);
+ }
+
public void setSize(int width, int height) {
mWidth = width;
mHeight = height;
@@ -349,10 +366,12 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
final int COLOR_PLANES_PER_VERTEX = 4;
private final int colorStride = COLOR_PLANES_PER_VERTEX * 4; // bytes per vertex
+ private float period;
+
// Set color with red, green, blue and alpha (opacity) values
// float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
- public Square() {
+ public Square(float period) {
for (int i=0; i<vertexCount; i++) {
cornerFrequencies[i] = 1f + (float)(Math.random() * 5);
}
@@ -401,6 +420,7 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
checkGlError("glGetAttribLocation(a_color)");
glEnableVertexAttribArray(mColorHandle);
checkGlError("glEnableVertexAttribArray");
+ this.period = period;
}
final float[] _tmphsv = new float[3];
@@ -408,7 +428,7 @@ final class ColorsGLRenderer implements Choreographer.FrameCallback {
// same thing for colors
long now = SystemClock.uptimeMillis();
colorBuffer.clear();
- final float t = now / 4000f; // set the base period to 4sec
+ final float t = now * period; // set the base period to 4sec
for(int i=0; i<vertexCount; i++) {
final float freq = (float) Math.sin(2 * Math.PI * t / cornerFrequencies[i]);
_tmphsv[0] = HUES[(i + cornerRotation) % vertexCount];
diff --git a/src/com/android/dreams/basic/ColorsLockScreen.java b/src/com/android/dreams/basic/ColorsLockScreen.java
new file mode 100644
index 0000000..baee696
--- /dev/null
+++ b/src/com/android/dreams/basic/ColorsLockScreen.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dreams.basic;
+
+import android.graphics.SurfaceTexture;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+import android.view.TextureView;
+import android.view.View;
+import cyanogenmod.externalviews.KeyguardExternalViewProviderService;
+
+/**
+ * Plays a delightful show of colors.
+ * <p>
+ * This dream performs its rendering using OpenGL on a separate rendering thread.
+ * </p>
+ */
+public class ColorsLockScreen extends KeyguardExternalViewProviderService {
+ static final String TAG = ColorsLockScreen.class.getSimpleName();
+ static final boolean DEBUG = false;
+
+ public static void LOG(String fmt, Object... args) {
+ if (!DEBUG) return;
+ Log.v(TAG, String.format(fmt, args));
+ }
+
+ @Override
+ protected Provider createExternalView(Bundle options) {
+ return new ProviderImpl(options);
+ }
+
+ private class ProviderImpl extends Provider implements TextureView.SurfaceTextureListener {
+ private TextureView mTextureView;
+
+ // The handler thread and handler on which the GL renderer is running.
+ private HandlerThread mRendererHandlerThread;
+ private Handler mRendererHandler;
+
+ // The current GL renderer, or null if the dream is not running.
+ private ColorsGLRenderer mRenderer;
+
+ protected ProviderImpl(Bundle options) {
+ super(options);
+ }
+
+ @Override
+ protected View onCreateView() {
+ mTextureView = new TextureView(ColorsLockScreen.this);
+ mTextureView.setSurfaceTextureListener(this);
+
+ return mTextureView;
+ }
+
+ @Override
+ protected void onKeyguardShowing(boolean screenOn) {
+ resumeRendering();
+ }
+
+ @Override
+ protected void onKeyguardDismissed() {
+ pauseRendering();
+ }
+
+ @Override
+ protected void onBouncerShowing(boolean showing) {
+ }
+
+ @Override
+ protected void onScreenTurnedOn() {
+ resumeRendering();
+ }
+
+ @Override
+ protected void onScreenTurnedOff() {
+ pauseRendering();
+ }
+
+ @Override
+ public void onSurfaceTextureAvailable(final SurfaceTexture surface,
+ final int width, final int height) {
+ LOG("onSurfaceTextureAvailable(%s, %d, %d)", surface, width, height);
+
+ if (mRendererHandlerThread == null) {
+ mRendererHandlerThread = new HandlerThread(TAG);
+ mRendererHandlerThread.start();
+ mRendererHandler = new Handler(mRendererHandlerThread.getLooper());
+ }
+
+ mRendererHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mRenderer != null) {
+ mRenderer.stop();
+ }
+ mRenderer = new ColorsGLRenderer(surface, width, height, 1 / 3000f);
+ mRenderer.start();
+ }
+ });
+ }
+
+ @Override
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface,
+ final int width, final int height) {
+ LOG("onSurfaceTextureSizeChanged(%s, %d, %d)", surface, width, height);
+
+ mRendererHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mRenderer != null) {
+ mRenderer.setSize(width, height);
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+ LOG("onSurfaceTextureDestroyed(%s)", surface);
+
+ mRendererHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mRenderer != null) {
+ mRenderer.stop();
+ mRenderer = null;
+ }
+ mRendererHandlerThread.quit();
+ mRendererHandlerThread = null;
+ }
+ });
+
+ try {
+ mRendererHandlerThread.join();
+ } catch (InterruptedException e) {
+ LOG("Error while waiting for renderer", e);
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ LOG("onSurfaceTextureUpdated(%s)", surface);
+ }
+
+ private void pauseRendering() {
+ if (mRenderer != null) {
+ mRendererHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRenderer.pause();
+ }
+ });
+ }
+ }
+
+ private void resumeRendering() {
+ if (mRenderer != null) {
+ mRendererHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mRenderer.resume();
+ }
+ });
+ }
+ }
+ }
+}