/*
 * 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 android.app.WallpaperManager;
import android.content.ComponentCallbacks2;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.os.AsyncTask;
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 android.view.WindowManager;

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";
    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;

    @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() {
        mEngine = new DrawableEngine();
        return mEngine;
    }

    class DrawableEngine extends Engine {
        private final Runnable mUnloadWallpaperCallback = () -> {
            unloadWallpaper(false /* forgetSize */);
        };

        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 mDefaultDisplay;
        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
            mDefaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay();
            setOffsetNotificationsEnabled(false);

            updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo(), 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;
            }

            // Force the wallpaper to cover the screen in both dimensions
            int surfaceWidth = Math.max(displayInfo.logicalWidth, mBackgroundWidth);
            int surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight);

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

        private DisplayInfo getDefaultDisplayInfo() {
            mDefaultDisplay.getDisplayInfo(mTmpDisplayInfo);
            return mTmpDisplayInfo;
        }

        void drawFrame() {
            if (!mSurfaceValid) {
                return;
            }
            try {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawWallpaper");
                DisplayInfo displayInfo = getDefaultDisplayInfo();
                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) {
                    // 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 {
                        return mWallpaperManager.getBitmap(true /* hardware */);
                    } 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);
        }

        private 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(), getDefaultDisplayInfo(),
                    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);
                }
            }
        }
    }
}
