Loading packages/SystemUI/AndroidManifest.xml +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,11 @@ android:sharedUserId="android.uid.systemui" coreApp="true"> <!-- Using OpenGL ES 2.0 --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <!-- SysUI must be the one to define this permission; its name is referenced by the core OS. --> <permission android:name="android.permission.systemui.IDENTITY" Loading packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl 0 → 100644 +33 −0 Original line number Diff line number Diff line precision mediump float; uniform sampler2D uTexture; uniform float uCenterReveal; uniform float uReveal; uniform float uAod2Opacity; uniform int uAodMode; varying vec2 vTextureCoordinates; vec3 luminosity(vec3 color) { float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; return vec3(lum); } vec4 transform(vec3 diffuse) { // TODO: Add well comments here, tracking on b/123615467. vec3 lum = luminosity(diffuse); diffuse = mix(diffuse, lum, smoothstep(0., uCenterReveal, uReveal)); float val = mix(uReveal, uCenterReveal, step(uCenterReveal, uReveal)); diffuse = smoothstep(val, 1.0, diffuse); diffuse *= uAod2Opacity * (1. - smoothstep(uCenterReveal, 1., uReveal)); return vec4(diffuse.r, diffuse.g, diffuse.b, 1.); } void main() { vec4 fragColor = texture2D(uTexture, vTextureCoordinates); // TODO: Remove the branch logic here, tracking on b/123615467. if (uAodMode != 0) { gl_FragColor = transform(fragColor.rgb); } else { gl_FragColor = fragColor; } } No newline at end of file packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl 0 → 100644 +8 −0 Original line number Diff line number Diff line attribute vec4 aPosition; attribute vec2 aTextureCoordinates; varying vec2 vTextureCoordinates; void main() { vTextureCoordinates = aTextureCoordinates; gl_Position = aPosition; } No newline at end of file packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +157 −2 Original line number Diff line number Diff line Loading @@ -19,8 +19,11 @@ package com.android.systemui; import static android.view.Display.DEFAULT_DISPLAY; import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.RecordingCanvas; Loading @@ -28,7 +31,9 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region.Op; import android.hardware.display.DisplayManager; import android.opengl.GLSurfaceView; import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.Trace; import android.service.wallpaper.WallpaperService; Loading @@ -39,6 +44,7 @@ import android.view.Surface; import android.view.SurfaceHolder; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.glwallpaper.ImageWallpaperRenderer; import java.io.FileDescriptor; import java.io.IOException; Loading @@ -51,12 +57,17 @@ import java.io.PrintWriter; public class ImageWallpaper extends WallpaperService { private static final String TAG = "ImageWallpaper"; private static final String GL_LOG_TAG = "ImageWallpaperGL"; // TODO: Testing purpose, need to remove later, b/123616712. private static final String SENSOR_EVENT_AWAKE = "systemui.test.event.awake"; // TODO: Testing purpose, need to remove later, b/123616712. private static final String SENSOR_EVENT_SLEEP = "systemui.test.event.sleep"; private static final boolean DEBUG = false; private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu"; private static final long DELAY_FORGET_WALLPAPER = 5000; private WallpaperManager mWallpaperManager; private DrawableEngine mEngine; private GLEngine mGlEngine; @Override public void onCreate() { Loading @@ -73,10 +84,112 @@ public class ImageWallpaper extends WallpaperService { @Override public Engine onCreateEngine() { mEngine = new DrawableEngine(); return mEngine; mGlEngine = new GLEngine(this); return mGlEngine; } class GLEngine extends Engine { private GLWallpaperSurfaceView mWallpaperSurfaceView; GLEngine(Context context) { mWallpaperSurfaceView = new GLWallpaperSurfaceView(context); mWallpaperSurfaceView.setRenderer( new ImageWallpaperRenderer(context, mWallpaperSurfaceView)); mWallpaperSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); setOffsetNotificationsEnabled(true); } @Override public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) { if (mWallpaperSurfaceView != null) { mWallpaperSurfaceView.notifyAmbientModeChanged(inAmbientMode); } } @Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { if (mWallpaperSurfaceView != null) { mWallpaperSurfaceView.notifyOffsetsChanged(xOffset, yOffset); } } private class GLWallpaperSurfaceView extends GLSurfaceView implements ImageGLView { private SensorEventListener mEventListener; private WallpaperStatusListener mWallpaperChangedListener; // TODO: Testing purpose, need to remove later, b/123616712. /** * For testing only: adb shell am broadcast -a <INTENT> */ private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent == null) { return; } switch (intent.getAction()) { case SENSOR_EVENT_AWAKE: notifySensorEvents(true); break; case SENSOR_EVENT_SLEEP: notifySensorEvents(false); break; } } }; GLWallpaperSurfaceView(Context context) { super(context); setEGLContextClientVersion(2); // TODO: Testing purpose, need to remove later, b/123616712. if (Build.IS_DEBUGGABLE) { IntentFilter filter = new IntentFilter(); filter.addAction(SENSOR_EVENT_AWAKE); filter.addAction(SENSOR_EVENT_SLEEP); registerReceiver(mReceiver, filter); } } @Override public SurfaceHolder getHolder() { return getSurfaceHolder(); } @Override public void setRenderer(Renderer renderer) { super.setRenderer(renderer); mEventListener = (SensorEventListener) renderer; mWallpaperChangedListener = (WallpaperStatusListener) renderer; } private void notifySensorEvents(boolean reach) { if (mEventListener != null) { mEventListener.onSensorEvent(reach); } } private void notifyAmbientModeChanged(boolean inAmbient) { if (mWallpaperChangedListener != null) { mWallpaperChangedListener.onAmbientModeChanged(inAmbient); } } private void notifyOffsetsChanged(float xOffset, float yOffset) { if (mWallpaperChangedListener != null) { mWallpaperChangedListener.onOffsetsChanged( xOffset, yOffset, getHolder().getSurfaceFrame()); } } @Override public void render() { requestRender(); } } } // TODO: Remove this engine, tracking on b/123617158. class DrawableEngine extends Engine { private final Runnable mUnloadWallpaperCallback = () -> { unloadWallpaper(false /* forgetSize */); Loading Loading @@ -564,4 +677,46 @@ public class ImageWallpaper extends WallpaperService { } } } /** * A listener to trace sensor event. */ public interface SensorEventListener { /** * Called back while sensor event comes. * @param reach The status of sensor. */ void onSensorEvent(boolean reach); } /** * A listener to trace status of image wallpaper. */ public interface WallpaperStatusListener { /** * Called back while ambient mode changes. * @param inAmbientMode true if is in ambient mode, false otherwise. */ void onAmbientModeChanged(boolean inAmbientMode); /** * Called back while wallpaper offsets. * @param xOffset The offset portion along x. * @param yOffset The offset portion along y. */ void onOffsetsChanged(float xOffset, float yOffset, Rect frame); } /** * An abstraction for view of GLRenderer. */ public interface ImageGLView { /** * Ask the view to render. */ void render(); } } packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java 0 → 100644 +115 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.systemui.glwallpaper; import static android.opengl.GLES20.GL_FRAGMENT_SHADER; import static android.opengl.GLES20.GL_VERTEX_SHADER; import static android.opengl.GLES20.glAttachShader; import static android.opengl.GLES20.glCompileShader; import static android.opengl.GLES20.glCreateProgram; import static android.opengl.GLES20.glCreateShader; import static android.opengl.GLES20.glGetAttribLocation; import static android.opengl.GLES20.glGetUniformLocation; import static android.opengl.GLES20.glLinkProgram; import static android.opengl.GLES20.glShaderSource; import static android.opengl.GLES20.glUseProgram; import android.content.Context; import android.content.res.Resources; import android.util.Log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * This class takes charge of linking shader codes and then return a handle for OpenGL ES program. */ class ImageGLProgram { private static final String TAG = ImageGLProgram.class.getSimpleName(); private Context mContext; private int mProgramHandle; ImageGLProgram(Context context) { mContext = context.getApplicationContext(); } private int loadShaderProgram(int vertexId, int fragmentId) { final String vertexSrc = getShaderResource(vertexId); final String fragmentSrc = getShaderResource(fragmentId); final int vertexHandle = getShaderHandle(GL_VERTEX_SHADER, vertexSrc); final int fragmentHandle = getShaderHandle(GL_FRAGMENT_SHADER, fragmentSrc); return getProgramHandle(vertexHandle, fragmentHandle); } private String getShaderResource(int shaderId) { Resources res = mContext.getResources(); StringBuilder code = new StringBuilder(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(res.openRawResource(shaderId)))) { String nextLine; while ((nextLine = reader.readLine()) != null) { code.append(nextLine).append("\n"); } } catch (IOException | Resources.NotFoundException ex) { Log.d(TAG, "Can not read the shader source", ex); code = null; } return code == null ? "" : code.toString(); } private int getShaderHandle(int type, String src) { final int shader = glCreateShader(type); if (shader == 0) { Log.d(TAG, "Create shader failed, type=" + type); return 0; } glShaderSource(shader, src); glCompileShader(shader); return shader; } private int getProgramHandle(int vertexHandle, int fragmentHandle) { final int program = glCreateProgram(); if (program == 0) { Log.d(TAG, "Can not create OpenGL ES program"); return 0; } glAttachShader(program, vertexHandle); glAttachShader(program, fragmentHandle); glLinkProgram(program); return program; } boolean useGLProgram(int vertexResId, int fragmentResId) { mProgramHandle = loadShaderProgram(vertexResId, fragmentResId); glUseProgram(mProgramHandle); return true; } int getAttributeHandle(String name) { return glGetAttribLocation(mProgramHandle, name); } int getUniformHandle(String name) { return glGetUniformLocation(mProgramHandle, name); } } Loading
packages/SystemUI/AndroidManifest.xml +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,11 @@ android:sharedUserId="android.uid.systemui" coreApp="true"> <!-- Using OpenGL ES 2.0 --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <!-- SysUI must be the one to define this permission; its name is referenced by the core OS. --> <permission android:name="android.permission.systemui.IDENTITY" Loading
packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl 0 → 100644 +33 −0 Original line number Diff line number Diff line precision mediump float; uniform sampler2D uTexture; uniform float uCenterReveal; uniform float uReveal; uniform float uAod2Opacity; uniform int uAodMode; varying vec2 vTextureCoordinates; vec3 luminosity(vec3 color) { float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; return vec3(lum); } vec4 transform(vec3 diffuse) { // TODO: Add well comments here, tracking on b/123615467. vec3 lum = luminosity(diffuse); diffuse = mix(diffuse, lum, smoothstep(0., uCenterReveal, uReveal)); float val = mix(uReveal, uCenterReveal, step(uCenterReveal, uReveal)); diffuse = smoothstep(val, 1.0, diffuse); diffuse *= uAod2Opacity * (1. - smoothstep(uCenterReveal, 1., uReveal)); return vec4(diffuse.r, diffuse.g, diffuse.b, 1.); } void main() { vec4 fragColor = texture2D(uTexture, vTextureCoordinates); // TODO: Remove the branch logic here, tracking on b/123615467. if (uAodMode != 0) { gl_FragColor = transform(fragColor.rgb); } else { gl_FragColor = fragColor; } } No newline at end of file
packages/SystemUI/res/raw/image_wallpaper_vertex_shader.glsl 0 → 100644 +8 −0 Original line number Diff line number Diff line attribute vec4 aPosition; attribute vec2 aTextureCoordinates; varying vec2 vTextureCoordinates; void main() { vTextureCoordinates = aTextureCoordinates; gl_Position = aPosition; } No newline at end of file
packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +157 −2 Original line number Diff line number Diff line Loading @@ -19,8 +19,11 @@ package com.android.systemui; import static android.view.Display.DEFAULT_DISPLAY; import android.app.WallpaperManager; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.RecordingCanvas; Loading @@ -28,7 +31,9 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region.Op; import android.hardware.display.DisplayManager; import android.opengl.GLSurfaceView; import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.Trace; import android.service.wallpaper.WallpaperService; Loading @@ -39,6 +44,7 @@ import android.view.Surface; import android.view.SurfaceHolder; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.glwallpaper.ImageWallpaperRenderer; import java.io.FileDescriptor; import java.io.IOException; Loading @@ -51,12 +57,17 @@ import java.io.PrintWriter; public class ImageWallpaper extends WallpaperService { private static final String TAG = "ImageWallpaper"; private static final String GL_LOG_TAG = "ImageWallpaperGL"; // TODO: Testing purpose, need to remove later, b/123616712. private static final String SENSOR_EVENT_AWAKE = "systemui.test.event.awake"; // TODO: Testing purpose, need to remove later, b/123616712. private static final String SENSOR_EVENT_SLEEP = "systemui.test.event.sleep"; private static final boolean DEBUG = false; private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu"; private static final long DELAY_FORGET_WALLPAPER = 5000; private WallpaperManager mWallpaperManager; private DrawableEngine mEngine; private GLEngine mGlEngine; @Override public void onCreate() { Loading @@ -73,10 +84,112 @@ public class ImageWallpaper extends WallpaperService { @Override public Engine onCreateEngine() { mEngine = new DrawableEngine(); return mEngine; mGlEngine = new GLEngine(this); return mGlEngine; } class GLEngine extends Engine { private GLWallpaperSurfaceView mWallpaperSurfaceView; GLEngine(Context context) { mWallpaperSurfaceView = new GLWallpaperSurfaceView(context); mWallpaperSurfaceView.setRenderer( new ImageWallpaperRenderer(context, mWallpaperSurfaceView)); mWallpaperSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); setOffsetNotificationsEnabled(true); } @Override public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) { if (mWallpaperSurfaceView != null) { mWallpaperSurfaceView.notifyAmbientModeChanged(inAmbientMode); } } @Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { if (mWallpaperSurfaceView != null) { mWallpaperSurfaceView.notifyOffsetsChanged(xOffset, yOffset); } } private class GLWallpaperSurfaceView extends GLSurfaceView implements ImageGLView { private SensorEventListener mEventListener; private WallpaperStatusListener mWallpaperChangedListener; // TODO: Testing purpose, need to remove later, b/123616712. /** * For testing only: adb shell am broadcast -a <INTENT> */ private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent == null) { return; } switch (intent.getAction()) { case SENSOR_EVENT_AWAKE: notifySensorEvents(true); break; case SENSOR_EVENT_SLEEP: notifySensorEvents(false); break; } } }; GLWallpaperSurfaceView(Context context) { super(context); setEGLContextClientVersion(2); // TODO: Testing purpose, need to remove later, b/123616712. if (Build.IS_DEBUGGABLE) { IntentFilter filter = new IntentFilter(); filter.addAction(SENSOR_EVENT_AWAKE); filter.addAction(SENSOR_EVENT_SLEEP); registerReceiver(mReceiver, filter); } } @Override public SurfaceHolder getHolder() { return getSurfaceHolder(); } @Override public void setRenderer(Renderer renderer) { super.setRenderer(renderer); mEventListener = (SensorEventListener) renderer; mWallpaperChangedListener = (WallpaperStatusListener) renderer; } private void notifySensorEvents(boolean reach) { if (mEventListener != null) { mEventListener.onSensorEvent(reach); } } private void notifyAmbientModeChanged(boolean inAmbient) { if (mWallpaperChangedListener != null) { mWallpaperChangedListener.onAmbientModeChanged(inAmbient); } } private void notifyOffsetsChanged(float xOffset, float yOffset) { if (mWallpaperChangedListener != null) { mWallpaperChangedListener.onOffsetsChanged( xOffset, yOffset, getHolder().getSurfaceFrame()); } } @Override public void render() { requestRender(); } } } // TODO: Remove this engine, tracking on b/123617158. class DrawableEngine extends Engine { private final Runnable mUnloadWallpaperCallback = () -> { unloadWallpaper(false /* forgetSize */); Loading Loading @@ -564,4 +677,46 @@ public class ImageWallpaper extends WallpaperService { } } } /** * A listener to trace sensor event. */ public interface SensorEventListener { /** * Called back while sensor event comes. * @param reach The status of sensor. */ void onSensorEvent(boolean reach); } /** * A listener to trace status of image wallpaper. */ public interface WallpaperStatusListener { /** * Called back while ambient mode changes. * @param inAmbientMode true if is in ambient mode, false otherwise. */ void onAmbientModeChanged(boolean inAmbientMode); /** * Called back while wallpaper offsets. * @param xOffset The offset portion along x. * @param yOffset The offset portion along y. */ void onOffsetsChanged(float xOffset, float yOffset, Rect frame); } /** * An abstraction for view of GLRenderer. */ public interface ImageGLView { /** * Ask the view to render. */ void render(); } }
packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLProgram.java 0 → 100644 +115 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.systemui.glwallpaper; import static android.opengl.GLES20.GL_FRAGMENT_SHADER; import static android.opengl.GLES20.GL_VERTEX_SHADER; import static android.opengl.GLES20.glAttachShader; import static android.opengl.GLES20.glCompileShader; import static android.opengl.GLES20.glCreateProgram; import static android.opengl.GLES20.glCreateShader; import static android.opengl.GLES20.glGetAttribLocation; import static android.opengl.GLES20.glGetUniformLocation; import static android.opengl.GLES20.glLinkProgram; import static android.opengl.GLES20.glShaderSource; import static android.opengl.GLES20.glUseProgram; import android.content.Context; import android.content.res.Resources; import android.util.Log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * This class takes charge of linking shader codes and then return a handle for OpenGL ES program. */ class ImageGLProgram { private static final String TAG = ImageGLProgram.class.getSimpleName(); private Context mContext; private int mProgramHandle; ImageGLProgram(Context context) { mContext = context.getApplicationContext(); } private int loadShaderProgram(int vertexId, int fragmentId) { final String vertexSrc = getShaderResource(vertexId); final String fragmentSrc = getShaderResource(fragmentId); final int vertexHandle = getShaderHandle(GL_VERTEX_SHADER, vertexSrc); final int fragmentHandle = getShaderHandle(GL_FRAGMENT_SHADER, fragmentSrc); return getProgramHandle(vertexHandle, fragmentHandle); } private String getShaderResource(int shaderId) { Resources res = mContext.getResources(); StringBuilder code = new StringBuilder(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(res.openRawResource(shaderId)))) { String nextLine; while ((nextLine = reader.readLine()) != null) { code.append(nextLine).append("\n"); } } catch (IOException | Resources.NotFoundException ex) { Log.d(TAG, "Can not read the shader source", ex); code = null; } return code == null ? "" : code.toString(); } private int getShaderHandle(int type, String src) { final int shader = glCreateShader(type); if (shader == 0) { Log.d(TAG, "Create shader failed, type=" + type); return 0; } glShaderSource(shader, src); glCompileShader(shader); return shader; } private int getProgramHandle(int vertexHandle, int fragmentHandle) { final int program = glCreateProgram(); if (program == 0) { Log.d(TAG, "Can not create OpenGL ES program"); return 0; } glAttachShader(program, vertexHandle); glAttachShader(program, fragmentHandle); glLinkProgram(program); return program; } boolean useGLProgram(int vertexResId, int fragmentResId) { mProgramHandle = loadShaderProgram(vertexResId, fragmentResId); glUseProgram(mProgramHandle); return true; } int getAttributeHandle(String name) { return glGetAttribLocation(mProgramHandle, name); } int getUniformHandle(String name) { return glGetUniformLocation(mProgramHandle, name); } }