Fixed a race contidion in StorageManagerService
StorageManagerService#onVolumeStateChanged passes on a mutable
object to onVolumeStateChangedLocked and onVolumeStateChangedAsync.
This causes a race since the state of the object being passed can
be updated while onVolumeStateChangedAsync is processing it.
To fix this, a clone of the object is passed instead.
Bug: 174056195
Test: atest AdoptableHostTest
Test: atest com.android.tests.fused.host.FuseDaemonHostTest
Change-Id: I4de32279ae740544bd3abe33d788ebdbef1eab00
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index e6bb088..3edc154 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -200,6 +200,21 @@
internalPath = parcel.readString8();
}
+ public VolumeInfo(VolumeInfo volumeInfo) {
+ this.id = volumeInfo.id;
+ this.type = volumeInfo.type;
+ this.disk = volumeInfo.disk;
+ this.partGuid = volumeInfo.partGuid;
+ this.mountFlags = volumeInfo.mountFlags;
+ this.mountUserId = volumeInfo.mountUserId;
+ this.state = volumeInfo.state;
+ this.fsType = volumeInfo.fsType;
+ this.fsUuid = volumeInfo.fsUuid;
+ this.fsLabel = volumeInfo.fsLabel;
+ this.path = volumeInfo.path;
+ this.internalPath = volumeInfo.internalPath;
+ }
+
@UnsupportedAppUsage
public static @NonNull String getEnvironmentForState(int state) {
final String envState = sStateToEnvironment.get(state);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1147db5..70ef44c 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1391,12 +1391,13 @@
final int oldState = vol.state;
final int newState = state;
vol.state = newState;
+ final VolumeInfo vInfo = new VolumeInfo(vol);
final SomeArgs args = SomeArgs.obtain();
- args.arg1 = vol;
+ args.arg1 = vInfo;
args.arg2 = oldState;
args.arg3 = newState;
mHandler.obtainMessage(H_VOLUME_STATE_CHANGED, args).sendToTarget();
- onVolumeStateChangedLocked(vol, oldState, newState);
+ onVolumeStateChangedLocked(vInfo, oldState, newState);
}
}
}