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

Commit 93997a8a authored by Mathias Agopian's avatar Mathias Agopian
Browse files

fix a crasher when setting a display to a null surface

Bug: 7076303
Change-Id: I843dd4ee4a603b8ad51bc1ad14e429db15050bec
parent c9ea4c8b
Loading
Loading
Loading
Loading
+32 −27
Original line number Original line Diff line number Diff line
@@ -944,7 +944,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
        if (!curr.isIdenticalTo(draw)) {
        if (!curr.isIdenticalTo(draw)) {
            mVisibleRegionsDirty = true;
            mVisibleRegionsDirty = true;
            const size_t cc = curr.size();
            const size_t cc = curr.size();
            const size_t dc = draw.size();
                  size_t dc = draw.size();


            // find the displays that were removed
            // find the displays that were removed
            // (ie: in drawing state but not in current state)
            // (ie: in drawing state but not in current state)
@@ -965,46 +965,51 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                    const wp<IBinder>& display(curr.keyAt(j));
                    const wp<IBinder>& display(curr.keyAt(j));
                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
                    if (state.surface->asBinder() != draw[i].surface->asBinder()) {
                        // changing the surface is like destroying and
                        // changing the surface is like destroying and
                        // recreating the DisplayDevice
                        // recreating the DisplayDevice, so we just remove it
                        sp<SurfaceTextureClient> stc(
                        // from the drawing state, so that it get re-added
                                new SurfaceTextureClient(state.surface));
                        // below.
                        sp<DisplayDevice> disp = new DisplayDevice(this,
                        mDisplays.removeItem(display);
                            state.type, display, stc, NULL, mEGLConfig);
                        mDrawingState.displays.removeItemsAt(i);

                        dc--; i--;
                        disp->setLayerStack(state.layerStack);
                        // at this point we must loop to the next item
                        disp->setOrientation(state.orientation);
                        continue;
                        // TODO: take viewport and frame into account
                        mDisplays.replaceValueFor(display, disp);
                    }
                    }
                    if (state.layerStack != draw[i].layerStack) {

                    const sp<DisplayDevice>& disp(getDisplayDevice(display));
                    const sp<DisplayDevice>& disp(getDisplayDevice(display));
                    if (disp != NULL) {
                        if (state.layerStack != draw[i].layerStack) {
                            disp->setLayerStack(state.layerStack);
                            disp->setLayerStack(state.layerStack);
                        }
                        }
                        if (state.orientation != draw[i].orientation ||
                        if (state.orientation != draw[i].orientation ||
                                state.viewport != draw[i].viewport ||
                                state.viewport != draw[i].viewport ||
                                state.frame != draw[i].frame) {
                                state.frame != draw[i].frame) {
                        const sp<DisplayDevice>& disp(getDisplayDevice(display));
                            disp->setOrientation(state.orientation);
                            disp->setOrientation(state.orientation);
                            // TODO: take viewport and frame into account
                            // TODO: take viewport and frame into account
                        }
                        }
                    }
                    }
                }
                }
            }


            // find displays that were added
            // find displays that were added
            // (ie: in current state but not in drawing state)
            // (ie: in current state but not in drawing state)
            for (size_t i=0 ; i<cc ; i++) {
            for (size_t i=0 ; i<cc ; i++) {
                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
                if (draw.indexOfKey(curr.keyAt(i)) < 0) {
                    const DisplayDeviceState& state(curr[i]);
                    const DisplayDeviceState& state(curr[i]);
                    if (state.surface != NULL) {
                        sp<SurfaceTextureClient> stc(
                        sp<SurfaceTextureClient> stc(
                                new SurfaceTextureClient(state.surface));
                                new SurfaceTextureClient(state.surface));
                        const wp<IBinder>& display(curr.keyAt(i));
                        const wp<IBinder>& display(curr.keyAt(i));
                        sp<DisplayDevice> disp = new DisplayDevice(this,
                        sp<DisplayDevice> disp = new DisplayDevice(this,
                                state.type, display, stc, 0, mEGLConfig);
                                state.type, display, stc, 0, mEGLConfig);
                        disp->setLayerStack(state.layerStack);
                        disp->setOrientation(state.orientation);
                        // TODO: take viewport and frame into account
                        mDisplays.add(display, disp);
                        mDisplays.add(display, disp);
                    }
                    }
                }
                }
            }
            }
        }
        }
    }


    /*
    /*
     * Perform our own transaction if needed
     * Perform our own transaction if needed