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

Commit a0c92d49 authored by Vairavan Srinivasan's avatar Vairavan Srinivasan
Browse files

Fix for the race in Wallpaperservice

Wallpaperservice has a race among message handler of
DO_DETACH and service's onDestroy. In certain cases,
the engine kept track in mActiveEngies is removed by
message handler of DO_DETACH and service's onDestroy
doesn't get an entry in mActiveEngines and isn't able
to invoke detach on it. This keeps the broadcast
receiver mReceiver active and causes the framework to
report a leak and unregister the receiver.

Meanwhile, the message handler of DO_DETACH continues
and invokes detach on the mEngine, which tries to
unregister the receiver, mReceiver and framework throws
an exception "Receiver not registered" and causes the
framework to reboot.

In case of system_server, WindowManagerPolicy and
android.server.ServerThread contest for access of
shared members. Fix is to protect the critical section
with a synchronized block.

Change-Id: I506b9453aecb0a121c2029443ae9c175d7c12af6
parent f82fa927
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -763,6 +763,7 @@ public abstract class WallpaperService extends Service {
        }
        
        void detach() {
           synchronized (mLock) {
            if (mDestroyed) {
                return;
            }
@@ -806,6 +807,7 @@ public abstract class WallpaperService extends Service {
            }
           }
        }
    }
    
    class IWallpaperEngineWrapper extends IWallpaperEngine.Stub
            implements HandlerCaller.Callback {
@@ -874,13 +876,17 @@ public abstract class WallpaperService extends Service {
                    }
                    Engine engine = onCreateEngine();
                    mEngine = engine;
                    synchronized (mActiveEngines) {
                        mActiveEngines.add(engine);
                    }
                    engine.attach(this);
                    return;
                }
                case DO_DETACH: {
                    mActiveEngines.remove(mEngine);
                    mEngine.detach();
                    synchronized (mActiveEngines) {
                        mActiveEngines.remove(mEngine);
                    }
                    return;
                }
                case DO_SET_DESIRED_SIZE: {
@@ -958,11 +964,13 @@ public abstract class WallpaperService extends Service {
    @Override
    public void onDestroy() {
        super.onDestroy();
        synchronized (mActiveEngines) {
           for (int i=0; i<mActiveEngines.size(); i++) {
               mActiveEngines.get(i).detach();
           }
           mActiveEngines.clear();
        }
    }

    /**
     * Implement to return the implementation of the internal accessibility