From 5fb5df001332d5fb05152e7a78d0b28a48ca559e Mon Sep 17 00:00:00 2001 From: Rickard Helldin Date: Fri, 7 Feb 2014 09:35:04 +0100 Subject: [PATCH] Fix, MountService now only sends one onShutDownComplete The event onShutDownComplete are sent only when all volumes are shutdown. (Not one for every volume.) Change-Id: I6af521ee8285ca581efac7d3c5f013dfbff3ee30 --- .../java/com/android/server/MountService.java | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 816ae6967cfd4..f73a92be96947 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -91,6 +91,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -384,18 +385,37 @@ class MountService extends IMountService.Stub } class ShutdownCallBack extends UnmountCallBack { - IMountShutdownObserver observer; - ShutdownCallBack(String path, IMountShutdownObserver observer) { + MountShutdownLatch mMountShutdownLatch; + ShutdownCallBack(String path, final MountShutdownLatch mountShutdownLatch) { super(path, true, false); - this.observer = observer; + mMountShutdownLatch = mountShutdownLatch; } @Override void handleFinished() { int ret = doUnmountVolume(path, true, removeEncryption); - if (observer != null) { + Slog.i(TAG, "Unmount completed: " + path + ", result code: " + ret); + mMountShutdownLatch.countDown(); + } + } + + static class MountShutdownLatch { + private IMountShutdownObserver mObserver; + private AtomicInteger mCount; + + MountShutdownLatch(final IMountShutdownObserver observer, int count) { + mObserver = observer; + mCount = new AtomicInteger(count); + } + + void countDown() { + boolean sendShutdown = false; + if (mCount.decrementAndGet() == 0) { + sendShutdown = true; + } + if (sendShutdown && mObserver != null) { try { - observer.onShutDownComplete(ret); + mObserver.onShutDownComplete(StorageResultCode.OperationSucceeded); } catch (RemoteException e) { Slog.w(TAG, "RemoteException when shutting down"); } @@ -1426,6 +1446,10 @@ class MountService extends IMountService.Stub Slog.i(TAG, "Shutting down"); synchronized (mVolumesLock) { + // Get all volumes to be unmounted. + MountShutdownLatch mountShutdownLatch = new MountShutdownLatch(observer, + mVolumeStates.size()); + for (String path : mVolumeStates.keySet()) { String state = mVolumeStates.get(path); @@ -1461,19 +1485,16 @@ class MountService extends IMountService.Stub if (state.equals(Environment.MEDIA_MOUNTED)) { // Post a unmount message. - ShutdownCallBack ucb = new ShutdownCallBack(path, observer); + ShutdownCallBack ucb = new ShutdownCallBack(path, mountShutdownLatch); mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb)); } else if (observer != null) { /* - * Observer is waiting for onShutDownComplete when we are done. - * Since nothing will be done send notification directly so shutdown - * sequence can continue. + * Count down, since nothing will be done. The observer will be + * notified when we are done so shutdown sequence can continue. */ - try { - observer.onShutDownComplete(StorageResultCode.OperationSucceeded); - } catch (RemoteException e) { - Slog.w(TAG, "RemoteException when shutting down"); - } + mountShutdownLatch.countDown(); + Slog.i(TAG, "Unmount completed: " + path + + ", result code: " + StorageResultCode.OperationSucceeded); } } }