Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cc9a315 authored by Winson Chung's avatar Winson Chung
Browse files

Manually recycling bitmap memory when rotating ss, resetting canvas bitmap,...

Manually recycling bitmap memory when rotating ss, resetting canvas bitmap, adding logging. (Bug 7974275)

Change-Id: I1b0590a297610ee5fee4e68222144780ab6e55ec
parent b3778531
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.os.Environment;
import android.os.Process;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -86,6 +87,8 @@ class SaveImageInBackgroundData {
 */
class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Void,
        SaveImageInBackgroundData> {
    private static final String TAG = "SaveImageInBackgroundTask";

    private static final String SCREENSHOTS_DIR_NAME = "Screenshots";
    private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
    private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
@@ -138,6 +141,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
                            (shortSide - mImageHeight) / 2);
        c.drawBitmap(data.image, matrix, paint);
        c.drawColor(0x40FFFFFF);
        c.setBitmap(null);

        Bitmap croppedIcon = Bitmap.createScaledBitmap(preview, iconSize, iconSize, true);

@@ -167,6 +171,8 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
        mNotificationBuilder.setLargeIcon(croppedIcon);
        // But we still don't set it for the expanded view, allowing the smallIcon to show here.
        mNotificationStyle.bigLargeIcon(null);

        Log.d(TAG, "SaveImageInBackgroundTask constructor");
    }

    @Override
@@ -174,6 +180,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
        if (params.length != 1) return null;
        if (isCancelled()) {
            params[0].clearImage();
            Log.d(TAG, "doInBackground cancelled");
            return null;
        }

@@ -238,6 +245,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
            // mounted
            params[0].clearImage();
            params[0].result = 1;
            Log.d(TAG, "doInBackground failed");
        }

        // Recycle the bitmap data
@@ -245,6 +253,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
            image.recycle();
        }

        Log.d(TAG, "doInBackground complete");
        return params[0];
    }

@@ -253,6 +262,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
        if (isCancelled()) {
            params.finisher.run();
            params.clearImage();
            Log.d(TAG, "onPostExecute cancelled");
            return;
        }

@@ -280,6 +290,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
            mNotificationManager.notify(mNotificationId, n);
        }
        params.finisher.run();
        Log.d(TAG, "onPostExecute complete");
    }
}

@@ -290,6 +301,8 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
 *     type of gallery?
 */
class GlobalScreenshot {
    private static final String TAG = "GlobalScreenshot";

    private static final int SCREENSHOT_NOTIFICATION_ID = 789;
    private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
    private static final int SCREENSHOT_DROP_IN_DURATION = 430;
@@ -381,12 +394,15 @@ class GlobalScreenshot {
        // Setup the Camera shutter sound
        mCameraSound = new MediaActionSound();
        mCameraSound.load(MediaActionSound.SHUTTER_CLICK);

        Log.d(TAG, "GlobalScreenshot constructor");
    }

    /**
     * Creates a new worker thread and saves the screenshot to the media store.
     */
    private void saveScreenshotInWorkerThread(Runnable finisher) {
        Log.d(TAG, "saveScreenshotInWorkerThread");
        SaveImageInBackgroundData data = new SaveImageInBackgroundData();
        data.context = mContext;
        data.image = mScreenBitmap;
@@ -394,6 +410,7 @@ class GlobalScreenshot {
        data.finisher = finisher;
        if (mSaveInBgTask != null) {
            mSaveInBgTask.cancel(false);
            Log.d(TAG, "saveScreenshotInWorkerThread cancel");
        }
        mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data, mNotificationManager,
                SCREENSHOT_NOTIFICATION_ID).execute(data);
@@ -418,6 +435,8 @@ class GlobalScreenshot {
     * Takes a screenshot of the current display and shows an animation.
     */
    void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
        Log.d(TAG, "takeScreenshot");

        // We need to orient the screenshot correctly (and the Surface api seems to take screenshots
        // only in the natural orientation of the device :!)
        mDisplay.getRealMetrics(mDisplayMetrics);
@@ -431,6 +450,8 @@ class GlobalScreenshot {
            mDisplayMatrix.mapPoints(dims);
            dims[0] = Math.abs(dims[0]);
            dims[1] = Math.abs(dims[1]);

            Log.d(TAG, "takeScreenshot requiresRotation");
        }

        // Take the screenshot
@@ -438,6 +459,7 @@ class GlobalScreenshot {
        if (mScreenBitmap == null) {
            notifyScreenshotError(mContext, mNotificationManager);
            finisher.run();
            Log.d(TAG, "takeScreenshot null bitmap");
            return;
        }

@@ -451,7 +473,10 @@ class GlobalScreenshot {
            c.translate(-dims[0] / 2, -dims[1] / 2);
            c.drawBitmap(mScreenBitmap, 0, 0, null);
            c.setBitmap(null);
            // Recycle the previous bitmap
            mScreenBitmap.recycle();
            mScreenBitmap = ss;
            Log.d(TAG, "takeScreenshot rotation bitmap created");
        }

        // Optimizations
@@ -461,6 +486,7 @@ class GlobalScreenshot {
        // Start the post-screenshot animation
        startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
                statusBarVisible, navBarVisible);
        Log.d(TAG, "takeScreenshot startedAnimation");
    }


@@ -469,6 +495,7 @@ class GlobalScreenshot {
     */
    private void startAnimation(final Runnable finisher, int w, int h, boolean statusBarVisible,
            boolean navBarVisible) {
        Log.d(TAG, "startAnimation");
        // Add the view for the animation
        mScreenshotView.setImageBitmap(mScreenBitmap);
        mScreenshotLayout.requestFocus();
@@ -477,9 +504,11 @@ class GlobalScreenshot {
        if (mScreenshotAnimation != null) {
            mScreenshotAnimation.end();
            mScreenshotAnimation.removeAllListeners();
            Log.d(TAG, "startAnimation reset previous animations");
        }

        mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
        Log.d(TAG, "startAnimation layout added to WM");
        ValueAnimator screenshotDropInAnim = createScreenshotDropInAnimation();
        ValueAnimator screenshotFadeOutAnim = createScreenshotDropOutAnimation(w, h,
                statusBarVisible, navBarVisible);
@@ -495,6 +524,7 @@ class GlobalScreenshot {
                // Clear any references to the bitmap
                mScreenBitmap = null;
                mScreenshotView.setImageBitmap(null);
                Log.d(TAG, "startAnimation onAnimationEnd");
            }
        });
        mScreenshotLayout.post(new Runnable() {
@@ -506,6 +536,7 @@ class GlobalScreenshot {
                mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                mScreenshotView.buildLayer();
                mScreenshotAnimation.start();
                Log.d(TAG, "startAnimation post runnable");
            }
        });
    }
@@ -643,6 +674,7 @@ class GlobalScreenshot {
    }

    static void notifyScreenshotError(Context context, NotificationManager nManager) {
        Log.d(TAG, "notifyScreenshotError");
        Resources r = context.getResources();

        // Clear all existing notification, compose the new notification and show it
+4 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class TakeScreenshotService extends Service {
    private static final String TAG = "TakeScreenshotService";
@@ -37,12 +38,15 @@ public class TakeScreenshotService extends Service {
                    final Messenger callback = msg.replyTo;
                    if (mScreenshot == null) {
                        mScreenshot = new GlobalScreenshot(TakeScreenshotService.this);
                        Log.d(TAG, "Global screenshot initialized");
                    }
                    Log.d(TAG, "Global screenshot captured");
                    mScreenshot.takeScreenshot(new Runnable() {
                        @Override public void run() {
                            Message reply = Message.obtain(null, 1);
                            try {
                                callback.send(reply);
                                Log.d(TAG, "Global screenshot completed");
                            } catch (RemoteException e) {
                            }
                        }