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

Commit d0c879bc authored by Daniel Norman's avatar Daniel Norman
Browse files

Ensure the MagThumbnail view is always inflated on the main thread.

I believe this is one cause of deadlock, in addition to going against
best practice that View inflation should only run on the main thread.

At the same time:
(1a) android.bg thread: FullScreenMagnificationController locks
    A11yManagerService.mLock when calling onUserStateChanged.
(1b) AudioService thread: AudioService locks A11yManager.mLock
    when checking A11yManager.isTouchExplorationEnabled

Then, at the same time:
(2a) android.bg thread: FullScreenMagnificationController inflates
    MagnificationThumbnail which is waiting to lock A11yManager.mLock
    in order to check A11yManager.isEnabled
(2b) AudioService thread: A11yManager.isTouchExplorationEnabled is
    waiting to lock A11yManagerService.mLock in order to register the
    A11yManager client.

By posting the View inflation to the system_server main thread we allow
1a to release its A11yManagerService.mLock so that 2b can proceed, releasing A11yManager.mLock (locked in 1b) so that 2a can proceed.

Bug: 287127293
Test: Log the thread ID/label of the mag thumbnail layout inflation,
      ensure it is the main thread
Change-Id: Ibe2574e5c83729d749befd343299fb26e3036037
parent 442bbb16
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -56,9 +56,9 @@ public class MagnificationThumbnail {
    private final Handler mHandler;

    @VisibleForTesting
    public final FrameLayout mThumbnailLayout;
    public FrameLayout mThumbnailLayout;

    private final View mThumbnailView;
    private View mThumbnailView;
    private int mThumbnailWidth;
    private int mThumbnailHeight;

@@ -79,13 +79,18 @@ public class MagnificationThumbnail {
        mWindowManager = windowManager;
        mHandler = handler;
        mWindowBounds =  mWindowManager.getCurrentWindowMetrics().getBounds();
        mBackgroundParams = createLayoutParams();
        mThumbnailWidth = 0;
        mThumbnailHeight = 0;
        mHandler.post(this::createThumbnailLayout);
    }

    @MainThread
    private void createThumbnailLayout() {
        mThumbnailLayout = (FrameLayout) LayoutInflater.from(mContext)
                .inflate(R.layout.thumbnail_background_view, /* root: */ null);
        mThumbnailView =
                mThumbnailLayout.findViewById(R.id.accessibility_magnification_thumbnail_view);
        mBackgroundParams = createLayoutParams();
        mThumbnailWidth = 0;
        mThumbnailHeight = 0;
    }

    /**