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

Commit 6cdf51f2 authored by Craig Mautner's avatar Craig Mautner
Browse files

Don't use finalize on ActivityView to cleanup.

Use a static object to contain the IActivityContainer reference
rather than storing it directly in the ActivityView itself. Then
when the ActivityView gives up the reference we can use a clean
finalize() call to release the IActivityContainer.

Fixes bug 14184756.

Change-Id: I7e05fcce3040b2b958f7c9cd030d5e3b745f3169
parent f4c909bc
Loading
Loading
Loading
Loading
+88 −47
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ public class ActivityView extends ViewGroup {

    DisplayMetrics mMetrics;
    private final TextureView mTextureView;
    private IActivityContainer mActivityContainer;
    private ActivityContainerWrapper mActivityContainer;
    private Activity mActivity;
    private int mWidth;
    private int mHeight;
@@ -56,8 +56,6 @@ public class ActivityView extends ViewGroup {
    IIntentSender mQueuedPendingIntent;
    Intent mQueuedIntent;

    private final CloseGuard mGuard = CloseGuard.get();

    public ActivityView(Context context) {
        this(context, null);
    }
@@ -81,8 +79,9 @@ public class ActivityView extends ViewGroup {
        }

        try {
            mActivityContainer = ActivityManagerNative.getDefault().createActivityContainer(
                    mActivity.getActivityToken(), new ActivityContainerCallback(this));
            mActivityContainer = new ActivityContainerWrapper(
                    ActivityManagerNative.getDefault().createActivityContainer(
                            mActivity.getActivityToken(), new ActivityContainerCallback(this)));
        } catch (RemoteException e) {
            throw new IllegalStateException("ActivityView: Unable to create ActivityContainer. "
                    + e);
@@ -96,8 +95,6 @@ public class ActivityView extends ViewGroup {
        mMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(mMetrics);

        mGuard.open("release");

        if (DEBUG) Log.v(TAG, "ctor()");
    }

@@ -107,11 +104,7 @@ public class ActivityView extends ViewGroup {
    }

    private boolean injectInputEvent(InputEvent event) {
        try {
        return mActivityContainer != null && mActivityContainer.injectEvent(event);
        } catch (RemoteException e) {
            return false;
        }
    }

    @Override
@@ -140,26 +133,13 @@ public class ActivityView extends ViewGroup {
        if (DEBUG) Log.v(TAG, "startActivity(): intent=" + intent + " " +
                (isAttachedToDisplay() ? "" : "not") + " attached");
        if (mSurface != null) {
            try {
            mActivityContainer.startActivity(intent);
            } catch (RemoteException e) {
                throw new IllegalStateException("ActivityView: Unable to startActivity. " + e);
            }
        } else {
            mQueuedIntent = intent;
            mQueuedPendingIntent = null;
        }
    }

    private void startActivityIntentSender(IIntentSender iIntentSender) {
        try {
            mActivityContainer.startActivityIntentSender(iIntentSender);
        } catch (RemoteException e) {
            throw new IllegalStateException(
                    "ActivityView: Unable to startActivity from IntentSender. " + e);
        }
    }

    public void startActivity(IntentSender intentSender) {
        if (mActivityContainer == null) {
            throw new IllegalStateException("Attempt to call startActivity after release");
@@ -168,7 +148,7 @@ public class ActivityView extends ViewGroup {
                (isAttachedToDisplay() ? "" : "not") + " attached");
        final IIntentSender iIntentSender = intentSender.getTarget();
        if (mSurface != null) {
            startActivityIntentSender(iIntentSender);
            mActivityContainer.startActivityIntentSender(iIntentSender);
        } else {
            mQueuedPendingIntent = iIntentSender;
            mQueuedIntent = null;
@@ -183,7 +163,7 @@ public class ActivityView extends ViewGroup {
                + (isAttachedToDisplay() ? "" : "not") + " attached");
        final IIntentSender iIntentSender = pendingIntent.getTarget();
        if (mSurface != null) {
            startActivityIntentSender(iIntentSender);
            mActivityContainer.startActivityIntentSender(iIntentSender);
        } else {
            mQueuedPendingIntent = iIntentSender;
            mQueuedIntent = null;
@@ -196,10 +176,7 @@ public class ActivityView extends ViewGroup {
            Log.e(TAG, "Duplicate call to release");
            return;
        }
        try {
        mActivityContainer.release();
        } catch (RemoteException e) {
        }
        mActivityContainer = null;

        if (mSurface != null) {
@@ -208,20 +185,6 @@ public class ActivityView extends ViewGroup {
        }

        mTextureView.setSurfaceTextureListener(null);

        mGuard.close();
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            if (mGuard != null) {
                mGuard.warnIfOpen();
                release();
            }
        } finally {
            super.finalize();
        }
    }

    private void attachToSurfaceWhenReady() {
@@ -247,7 +210,7 @@ public class ActivityView extends ViewGroup {
            startActivity(mQueuedIntent);
            mQueuedIntent = null;
        } else if (mQueuedPendingIntent != null) {
            startActivityIntentSender(mQueuedPendingIntent);
            mActivityContainer.startActivityIntentSender(mQueuedPendingIntent);
            mQueuedPendingIntent = null;
        }
    }
@@ -312,4 +275,82 @@ public class ActivityView extends ViewGroup {
                    " ActivityView=" + mActivityViewWeakReference.get());
        }
    }

    private static class ActivityContainerWrapper {
        private final IActivityContainer mIActivityContainer;
        private final CloseGuard mGuard = CloseGuard.get();

        ActivityContainerWrapper(IActivityContainer container) {
            mIActivityContainer = container;
            mGuard.open("release");
        }

        void attachToDisplay(int displayId) {
            try {
                mIActivityContainer.attachToDisplay(displayId);
            } catch (RemoteException e) {
            }
        }

        void setSurface(Surface surface, int width, int height, int density)
                throws RemoteException {
            mIActivityContainer.setSurface(surface, width, height, density);
        }

        int startActivity(Intent intent) {
            try {
                return mIActivityContainer.startActivity(intent);
            } catch (RemoteException e) {
                throw new IllegalStateException("ActivityView: Unable to startActivity. " + e);
            }
        }

        int startActivityIntentSender(IIntentSender intentSender) {
            try {
                return mIActivityContainer.startActivityIntentSender(intentSender);
            } catch (RemoteException e) {
                throw new IllegalStateException(
                        "ActivityView: Unable to startActivity from IntentSender. " + e);
            }
        }

        int getDisplayId() {
            try {
                return mIActivityContainer.getDisplayId();
            } catch (RemoteException e) {
                return -1;
            }
        }

        boolean injectEvent(InputEvent event) {
            try {
                return mIActivityContainer.injectEvent(event);
            } catch (RemoteException e) {
                return false;
            }
        }

        void release() {
            if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: release called");
            try {
                mIActivityContainer.release();
                mGuard.close();
            } catch (RemoteException e) {
            }
        }

        @Override
        protected void finalize() throws Throwable {
            if (DEBUG) Log.v(TAG, "ActivityContainerWrapper: finalize called");
            try {
                if (mGuard != null) {
                    mGuard.warnIfOpen();
                    release();
                }
            } finally {
                super.finalize();
            }
        }

    }
}