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

Commit bc57cd1b authored by Craig Mautner's avatar Craig Mautner
Browse files

Notify ViewRootImpl when it's safe to modify Canvas.

When Activity.convert{To|From}Translucent() is called the
ViewRootImpl is now notified when it is safe to convert the Canvas
from translucent to opaque and back to translucent. This will make
it possible to save resources when compositing opaque layers.

Fixes bug 10349536.

Change-Id: I7282aee1d54601fb00611d20be204bf164d873f6
parent 80f7ec06
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -747,6 +747,7 @@ public class Activity extends ContextThemeWrapper
    int mResultCode = RESULT_CANCELED;
    Intent mResultData = null;
    private TranslucentConversionListener mTranslucentCallback;
    private boolean mChangeCanvasToTranslucent;

    private boolean mTitleReady = false;

@@ -4903,7 +4904,9 @@ public class Activity extends ContextThemeWrapper
    public void convertFromTranslucent() {
        try {
            mTranslucentCallback = null;
            ActivityManagerNative.getDefault().convertFromTranslucent(mToken);
            if (ActivityManagerNative.getDefault().convertFromTranslucent(mToken)) {
                WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true);
            }
        } catch (RemoteException e) {
            // pass
        }
@@ -4931,6 +4934,7 @@ public class Activity extends ContextThemeWrapper
    public void convertToTranslucent(TranslucentConversionListener callback) {
        try {
            mTranslucentCallback = callback;
            mChangeCanvasToTranslucent =
                    ActivityManagerNative.getDefault().convertToTranslucent(mToken);
        } catch (RemoteException e) {
            // pass
@@ -4943,6 +4947,9 @@ public class Activity extends ContextThemeWrapper
            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
            mTranslucentCallback = null;
        }
        if (mChangeCanvasToTranslucent) {
            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
        }
    }

    /**
+10 −4
Original line number Diff line number Diff line
@@ -1502,16 +1502,18 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case CONVERT_FROM_TRANSLUCENT_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            convertFromTranslucent(token);
            boolean converted = convertFromTranslucent(token);
            reply.writeNoException();
            reply.writeInt(converted ? 1 : 0);
            return true;
        }

        case CONVERT_TO_TRANSLUCENT_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
            convertToTranslucent(token);
            boolean converted = convertToTranslucent(token);
            reply.writeNoException();
            reply.writeInt(converted ? 1 : 0);
            return true;
        }

@@ -3876,7 +3878,7 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    public void convertFromTranslucent(IBinder token)
    public boolean convertFromTranslucent(IBinder token)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
@@ -3884,11 +3886,13 @@ class ActivityManagerProxy implements IActivityManager
        data.writeStrongBinder(token);
        mRemote.transact(CONVERT_FROM_TRANSLUCENT_TRANSACTION, data, reply, 0);
        reply.readException();
        boolean res = reply.readInt() != 0;
        data.recycle();
        reply.recycle();
        return res;
    }

    public void convertToTranslucent(IBinder token)
    public boolean convertToTranslucent(IBinder token)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
@@ -3896,8 +3900,10 @@ class ActivityManagerProxy implements IActivityManager
        data.writeStrongBinder(token);
        mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0);
        reply.readException();
        boolean res = reply.readInt() != 0;
        data.recycle();
        reply.recycle();
        return res;
    }

    public void setImmersive(IBinder token, boolean immersive)
+2 −2
Original line number Diff line number Diff line
@@ -301,8 +301,8 @@ public interface IActivityManager extends IInterface {

    public void finishHeavyWeightApp() throws RemoteException;

    public void convertFromTranslucent(IBinder token) throws RemoteException;
    public void convertToTranslucent(IBinder token) throws RemoteException;
    public boolean convertFromTranslucent(IBinder token) throws RemoteException;
    public boolean convertToTranslucent(IBinder token) throws RemoteException;
    public void notifyActivityDrawn(IBinder token) throws RemoteException;

    public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
+5 −0
Original line number Diff line number Diff line
@@ -5967,6 +5967,11 @@ public final class ViewRootImpl implements ViewParent,
        // Do nothing.
    }

    void changeCanvasOpacity(boolean opaque) {
        // TODO(romainguy): recreate Canvas (software or hardware) to reflect the opacity change.
        Log.d(TAG, "changeCanvasOpacity: opaque=" + opaque);
    }

    class TakenSurfaceHolder extends BaseSurfaceHolder {
        @Override
        public boolean onAllowLockCanvas() {
+15 −0
Original line number Diff line number Diff line
@@ -496,6 +496,21 @@ public final class WindowManagerGlobal {
            }
        }
    }

    /** @hide */
    public void changeCanvasOpacity(IBinder token, boolean opaque) {
        if (token == null) {
            return;
        }
        synchronized (mLock) {
            for (int i = mParams.size() - 1; i >= 0; --i) {
                if (mParams.get(i).token == token) {
                    mRoots.get(i).changeCanvasOpacity(opaque);
                    return;
                }
            }
        }
    }
}

final class WindowLeaked extends AndroidRuntimeException {
Loading