/*
 * 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.
 */

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;
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;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
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;
import java.io.PrintWriter;

/**
 * Default built-in wallpaper that simply shows a static image.
 */
@SuppressWarnings({"UnusedDeclaration"})
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() {
        super.onCreate();
        mWallpaperManager = getSystemService(WallpaperManager.class);
    }

    @Override
    public void onTrimMemory(int level) {
        if (mEngine != null) {
            mEngine.trimMemory(level);
        }
    }

    @Override
    public Engine onCreateEngine() {
        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 */);
        };

        // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
        // set min to 64 px (CTS covers this)
        @VisibleForTesting
        static final int MIN_BACKGROUND_WIDTH = 64;
        @VisibleForTesting
        static final int MIN_BACKGROUND_HEIGHT = 64;

        Bitmap mBackground;
        int mBackgroundWidth = -1, mBackgroundHeight = -1;
        int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
        int mLastRotation = -1;
        float mXOffset = 0f;
        float mYOffset = 0f;
        float mScale = 1f;

        private Display mDisplay;
        private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();

        boolean mVisible = true;
        boolean mOffsetsChanged;
        int mLastXTranslation;
        int mLastYTranslation;

        private int mRotationAtLastSurfaceSizeUpdate = -1;
        private int mDisplayWidthAtLastSurfaceSizeUpdate = -1;
        private int mDisplayHeightAtLastSurfaceSizeUpdate = -1;

        private int mLastRequestedWidth = -1;
        private int mLastRequestedHeight = -1;
        private AsyncTask<Void, Void, Bitmap> mLoader;
        private boolean mNeedsDrawAfterLoadingWallpaper;
        private boolean mSurfaceValid;
        private boolean mSurfaceRedrawNeeded;

        DrawableEngine() {
            super();
            setFixedSizeAllowed(true);
        }

        void trimMemory(int level) {
            if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW
                    && level <= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL
                    && mBackground != null) {
                if (DEBUG) {
                    Log.d(TAG, "trimMemory");
                }
                unloadWallpaper(true /* forgetSize */);
            }
        }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            if (DEBUG) {
                Log.d(TAG, "onCreate");
            }

            super.onCreate(surfaceHolder);

            //noinspection ConstantConditions
            final Context displayContext = getDisplayContext();
            final int displayId = displayContext == null ? DEFAULT_DISPLAY :
                    displayContext.getDisplayId();
            DisplayManager dm = getSystemService(DisplayManager.class);
            if (dm != null) {
                mDisplay = dm.getDisplay(displayId);
                if (mDisplay == null) {
                    Log.e(TAG, "Cannot find display! Fallback to default.");
                    mDisplay = dm.getDisplay(DEFAULT_DISPLAY);
                }
            }
            setOffsetNotificationsEnabled(false);

            updateSurfaceSize(surfaceHolder, getDisplayInfo(), false /* forDraw */);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mBackground = null;
            unloadWallpaper(true /* forgetSize */);
        }

        boolean updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo,
                boolean forDraw) {
            boolean hasWallpaper = true;

            // Load background image dimensions, if we haven't saved them yet
            if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
                // Need to load the image to get dimensions
                loadWallpaper(forDraw);
                if (DEBUG) {
                    Log.d(TAG, "Reloading, redoing updateSurfaceSize later.");
                }
                hasWallpaper = false;
            }

            // Expected surface size.
            int surfaceWidth = Math.max(displayInfo.logicalWidth, mBackgroundWidth);
            int surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight);

            // Calculate the minimum drawing area of the surface, which saves memory and does not
            // distort the image.
            final float scale = Math.min(
                    (float) mBackgroundHeight / (float) surfaceHeight,
                    (float) mBackgroundWidth / (float) surfaceWidth);
            surfaceHeight = (int) (scale * surfaceHeight);
            surfaceWidth = (int) (scale * surfaceWidth);

            // Set surface size to at least MIN size.
            if (surfaceWidth < MIN_BACKGROUND_WIDTH || surfaceHeight < MIN_BACKGROUND_HEIGHT) {
                final float scaleUp = Math.max(
                        (float) MIN_BACKGROUND_WIDTH / (float) surfaceWidth,
                        (float) MIN_BACKGROUND_HEIGHT / (float) surfaceHeight);
                surfaceWidth = (int) ((float) surfaceWidth * scaleUp);
                surfaceHeight = (int) ((float) surfaceHeight * scaleUp);
            }

            // Used a fixed size surface, because we are special.  We can do
            // this because we know the current design of window animations doesn't
            // cause this to break.
            surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight);
            mLastRequestedWidth = surfaceWidth;
            mLastRequestedHeight = surfaceHeight;

            return hasWallpaper;
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            if (DEBUG) {
                Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible);
            }

            if (mVisible != visible) {
                if (DEBUG) {
                    Log.d(TAG, "Visibility changed to visible=" + visible);
                }
                mVisible = visible;
                if (visible) {
                    drawFrame();
                }
            }
        }

        @Override
        public void onOffsetsChanged(float xOffset, float yOffset,
                float xOffsetStep, float yOffsetStep,
                int xPixels, int yPixels) {
            if (DEBUG) {
                Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset
                        + ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep
                        + ", xPixels=" + xPixels + ", yPixels=" + yPixels);
            }

            if (mXOffset != xOffset || mYOffset != yOffset) {
                if (DEBUG) {
                    Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ").");
                }
                mXOffset = xOffset;
                mYOffset = yOffset;
                mOffsetsChanged = true;
            }
            drawFrame();
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            if (DEBUG) {
                Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height);
            }

            super.onSurfaceChanged(holder, format, width, height);

            drawFrame();
        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            if (DEBUG) {
                Log.i(TAG, "onSurfaceDestroyed");
            }

            mLastSurfaceWidth = mLastSurfaceHeight = -1;
            mSurfaceValid = false;
        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
            if (DEBUG) {
                Log.i(TAG, "onSurfaceCreated");
            }

            mLastSurfaceWidth = mLastSurfaceHeight = -1;
            mSurfaceValid = true;
        }

        @Override
        public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
            if (DEBUG) {
                Log.d(TAG, "onSurfaceRedrawNeeded");
            }
            super.onSurfaceRedrawNeeded(holder);
            // At the end of this method we should have drawn into the surface.
            // This means that the bitmap should be loaded synchronously if
            // it was already unloaded.
            if (mBackground == null) {
                updateBitmap(mWallpaperManager.getBitmap(true /* hardware */));
            }
            mSurfaceRedrawNeeded = true;
            drawFrame();
        }

        @VisibleForTesting
        DisplayInfo getDisplayInfo() {
            mDisplay.getDisplayInfo(mTmpDisplayInfo);
            return mTmpDisplayInfo;
        }

        void drawFrame() {
            if (!mSurfaceValid) {
                return;
            }
            try {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawWallpaper");
                DisplayInfo displayInfo = getDisplayInfo();
                int newRotation = displayInfo.rotation;

                // Sometimes a wallpaper is not large enough to cover the screen in one dimension.
                // Call updateSurfaceSize -- it will only actually do the update if the dimensions
                // should change
                if (newRotation != mLastRotation
                        || mDisplayWidthAtLastSurfaceSizeUpdate != displayInfo.logicalWidth
                        || mDisplayHeightAtLastSurfaceSizeUpdate != displayInfo.logicalHeight) {
                    // Update surface size (if necessary)
                    if (!updateSurfaceSize(getSurfaceHolder(), displayInfo, true /* forDraw */)) {
                        return; // had to reload wallpaper, will retry later
                    }
                    mRotationAtLastSurfaceSizeUpdate = newRotation;
                    mDisplayWidthAtLastSurfaceSizeUpdate = displayInfo.logicalWidth;
                    mDisplayHeightAtLastSurfaceSizeUpdate = displayInfo.logicalHeight;
                }
                SurfaceHolder sh = getSurfaceHolder();
                final Rect frame = sh.getSurfaceFrame();
                final int dw = frame.width();
                final int dh = frame.height();
                boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth
                        || dh != mLastSurfaceHeight;

                boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation
                        || mSurfaceRedrawNeeded || mNeedsDrawAfterLoadingWallpaper;
                if (!redrawNeeded && !mOffsetsChanged) {
                    if (DEBUG) {
                        Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
                                + "and offsets have not changed.");
                    }
                    return;
                }
                mLastRotation = newRotation;
                mSurfaceRedrawNeeded = false;

                // Load bitmap if it is not yet loaded
                if (mBackground == null) {
                    loadWallpaper(true);
                    if (DEBUG) {
                        Log.d(TAG, "Reloading, resuming draw later");
                    }
                    return;
                }

                // Left align the scaled image
                mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(),
                        dh / (float) mBackground.getHeight()));
                final int availw = (int) (mBackground.getWidth() * mScale) - dw;
                final int availh = (int) (mBackground.getHeight() * mScale) - dh;
                int xPixels = (int) (availw * mXOffset);
                int yPixels = (int) (availh * mYOffset);

                mOffsetsChanged = false;
                if (surfaceDimensionsChanged) {
                    mLastSurfaceWidth = dw;
                    mLastSurfaceHeight = dh;
                }
                if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
                    if (DEBUG) {
                        Log.d(TAG, "Suppressed drawFrame since the image has not "
                                + "actually moved an integral number of pixels.");
                    }
                    return;
                }
                mLastXTranslation = xPixels;
                mLastYTranslation = yPixels;

                if (DEBUG) {
                    Log.d(TAG, "Redrawing wallpaper");
                }

                drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
                scheduleUnloadWallpaper();
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }

        /**
         * Loads the wallpaper on background thread and schedules updating the surface frame,
         * and if {@param needsDraw} is set also draws a frame.
         *
         * If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to
         * the active request).
         *
         * If {@param needsReset} is set also clears the cache in WallpaperManager first.
         */
        private void loadWallpaper(boolean needsDraw) {
            mNeedsDrawAfterLoadingWallpaper |= needsDraw;
            if (mLoader != null) {
                if (DEBUG) {
                    Log.d(TAG, "Skipping loadWallpaper, already in flight ");
                }
                return;
            }
            mLoader = new AsyncTask<Void, Void, Bitmap>() {
                @Override
                protected Bitmap doInBackground(Void... params) {
                    Throwable exception;
                    try {
                        Bitmap wallpaper = mWallpaperManager.getBitmap(true /* hardware */);
                        if (wallpaper != null
                                && wallpaper.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) {
                            throw new RuntimeException("Wallpaper is too large to draw!");
                        }
                        return wallpaper;
                    } catch (RuntimeException | OutOfMemoryError e) {
                        exception = e;
                    }

                    if (isCancelled()) {
                        return null;
                    }

                    // Note that if we do fail at this, and the default wallpaper can't
                    // be loaded, we will go into a cycle.  Don't do a build where the
                    // default wallpaper can't be loaded.
                    Log.w(TAG, "Unable to load wallpaper!", exception);
                    try {
                        mWallpaperManager.clear();
                    } catch (IOException ex) {
                        // now we're really screwed.
                        Log.w(TAG, "Unable reset to default wallpaper!", ex);
                    }

                    if (isCancelled()) {
                        return null;
                    }

                    try {
                        return mWallpaperManager.getBitmap(true /* hardware */);
                    } catch (RuntimeException | OutOfMemoryError e) {
                        Log.w(TAG, "Unable to load default wallpaper!", e);
                    }
                    return null;
                }

                @Override
                protected void onPostExecute(Bitmap b) {
                    updateBitmap(b);

                    if (mNeedsDrawAfterLoadingWallpaper) {
                        drawFrame();
                    }

                    mLoader = null;
                    mNeedsDrawAfterLoadingWallpaper = false;
                }
            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }

        @VisibleForTesting
        void updateBitmap(Bitmap bitmap) {
            mBackground = null;
            mBackgroundWidth = -1;
            mBackgroundHeight = -1;

            if (bitmap != null) {
                mBackground = bitmap;
                mBackgroundWidth = mBackground.getWidth();
                mBackgroundHeight = mBackground.getHeight();
            }

            if (DEBUG) {
                Log.d(TAG, "Wallpaper loaded: " + mBackground);
            }
            updateSurfaceSize(getSurfaceHolder(), getDisplayInfo(),
                    false /* forDraw */);
        }

        private void unloadWallpaper(boolean forgetSize) {
            if (mLoader != null) {
                mLoader.cancel(false);
                mLoader = null;
            }
            mBackground = null;
            if (forgetSize) {
                mBackgroundWidth = -1;
                mBackgroundHeight = -1;
            }

            final Surface surface = getSurfaceHolder().getSurface();
            surface.hwuiDestroy();

            mWallpaperManager.forgetLoadedWallpaper();
        }

        private void scheduleUnloadWallpaper() {
            Handler handler = getMainThreadHandler();
            handler.removeCallbacks(mUnloadWallpaperCallback);
            handler.postDelayed(mUnloadWallpaperCallback, DELAY_FORGET_WALLPAPER);
        }

        @Override
        protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
            super.dump(prefix, fd, out, args);

            out.print(prefix); out.println("ImageWallpaper.DrawableEngine:");
            out.print(prefix); out.print(" mBackground="); out.print(mBackground);
            out.print(" mBackgroundWidth="); out.print(mBackgroundWidth);
            out.print(" mBackgroundHeight="); out.println(mBackgroundHeight);

            out.print(prefix); out.print(" mLastRotation="); out.print(mLastRotation);
            out.print(" mLastSurfaceWidth="); out.print(mLastSurfaceWidth);
            out.print(" mLastSurfaceHeight="); out.println(mLastSurfaceHeight);

            out.print(prefix); out.print(" mXOffset="); out.print(mXOffset);
            out.print(" mYOffset="); out.println(mYOffset);

            out.print(prefix); out.print(" mVisible="); out.print(mVisible);
            out.print(" mOffsetsChanged="); out.println(mOffsetsChanged);

            out.print(prefix); out.print(" mLastXTranslation="); out.print(mLastXTranslation);
            out.print(" mLastYTranslation="); out.print(mLastYTranslation);
            out.print(" mScale="); out.println(mScale);

            out.print(prefix); out.print(" mLastRequestedWidth="); out.print(mLastRequestedWidth);
            out.print(" mLastRequestedHeight="); out.println(mLastRequestedHeight);

            out.print(prefix); out.println(" DisplayInfo at last updateSurfaceSize:");
            out.print(prefix);
            out.print("  rotation="); out.print(mRotationAtLastSurfaceSizeUpdate);
            out.print("  width="); out.print(mDisplayWidthAtLastSurfaceSizeUpdate);
            out.print("  height="); out.println(mDisplayHeightAtLastSurfaceSizeUpdate);
        }

        private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int left, int top) {
            Canvas c = sh.lockHardwareCanvas();
            if (c != null) {
                try {
                    if (DEBUG) {
                        Log.d(TAG, "Redrawing: left=" + left + ", top=" + top);
                    }

                    final float right = left + mBackground.getWidth() * mScale;
                    final float bottom = top + mBackground.getHeight() * mScale;
                    if (w < 0 || h < 0) {
                        c.save(Canvas.CLIP_SAVE_FLAG);
                        c.clipRect(left, top, right, bottom,
                                Op.DIFFERENCE);
                        c.drawColor(0xff000000);
                        c.restore();
                    }
                    if (mBackground != null) {
                        RectF dest = new RectF(left, top, right, bottom);
                        Log.i(TAG, "Redrawing in rect: " + dest + " with surface size: "
                                + mLastRequestedWidth + "x" + mLastRequestedHeight);
                        c.drawBitmap(mBackground, null, dest, null);
                    }
                } finally {
                    sh.unlockCanvasAndPost(c);
                }
            }
        }
    }

    /**
     * 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();
    }
}
