Android: concurrency issue for Android_SetWindowFullscreen()
authorSylvain Becker <sylvain.becker@gmail.com>
Wed, 09 Jan 2019 15:18:41 +0100
changeset 12512afc8e5d1d992
parent 12511 0ef0e4cb7752
child 12513 efddb8c5e161
Android: concurrency issue for Android_SetWindowFullscreen()

It accesses data->native_window, which can be changed by onNativeSurfacedChanged().

Currently, Android_SetWindowFullscreen() may access data->native_window after it
has been released, and before a new reference is acquired.

(can be reproduced by adding some SDL_Delay() in onNativeSurfacedChanged and
Android_SetWindowFullscreen() ).
src/video/android/SDL_androidwindow.c
     1.1 --- a/src/video/android/SDL_androidwindow.c	Mon Jan 07 17:06:50 2019 +0100
     1.2 +++ b/src/video/android/SDL_androidwindow.c	Wed Jan 09 15:18:41 2019 +0100
     1.3 @@ -116,36 +116,45 @@
     1.4  void
     1.5  Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
     1.6  {
     1.7 -    /* If the window is being destroyed don't change visible state */
     1.8 -    if (!window->is_destroying) {
     1.9 -        Android_JNI_SetWindowStyle(fullscreen);
    1.10 +    SDL_LockMutex(Android_ActivityMutex);
    1.11 +
    1.12 +    if (window == Android_Window) {
    1.13 +
    1.14 +        /* If the window is being destroyed don't change visible state */
    1.15 +        if (!window->is_destroying) {
    1.16 +            Android_JNI_SetWindowStyle(fullscreen);
    1.17 +        }
    1.18 +
    1.19 +        /* Ensure our size matches reality after we've executed the window style change.
    1.20 +         *
    1.21 +         * It is possible that we've set width and height to the full-size display, but on
    1.22 +         * Samsung DeX or Chromebooks or other windowed Android environemtns, our window may
    1.23 +         * still not be the full display size.
    1.24 +         */
    1.25 +        if (!SDL_IsDeXMode() && !SDL_IsChromebook()) {
    1.26 +            goto endfunction;
    1.27 +        }
    1.28 +
    1.29 +        SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    1.30 +
    1.31 +        if (!data || !data->native_window) {
    1.32 +            goto endfunction;
    1.33 +        }
    1.34 +
    1.35 +        int old_w = window->w;
    1.36 +        int old_h = window->h;
    1.37 +
    1.38 +        int new_w = ANativeWindow_getWidth(data->native_window);
    1.39 +        int new_h = ANativeWindow_getHeight(data->native_window);
    1.40 +
    1.41 +        if (old_w != new_w || old_h != new_h) {
    1.42 +            SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
    1.43 +        }
    1.44      }
    1.45  
    1.46 -    /* Ensure our size matches reality after we've executed the window style change.
    1.47 -     *
    1.48 -     * It is possible that we've set width and height to the full-size display, but on
    1.49 -     * Samsung DeX or Chromebooks or other windowed Android environemtns, our window may 
    1.50 -     * still not be the full display size.
    1.51 -     */
    1.52 -    if (!SDL_IsDeXMode() && !SDL_IsChromebook()) {
    1.53 -        return;
    1.54 -    }
    1.55 +endfunction:
    1.56  
    1.57 -    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
    1.58 -
    1.59 -    if (!data || !data->native_window) {
    1.60 -        return;
    1.61 -    }
    1.62 -
    1.63 -    int old_w = window->w;
    1.64 -    int old_h = window->h;
    1.65 -
    1.66 -    int new_w = ANativeWindow_getWidth(data->native_window);
    1.67 -    int new_h = ANativeWindow_getHeight(data->native_window);
    1.68 -
    1.69 -    if (old_w != new_w || old_h != new_h) {
    1.70 -        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
    1.71 -    }
    1.72 +    SDL_UnlockMutex(Android_ActivityMutex);
    1.73  }
    1.74  
    1.75  void