Merge changes I17264f0e,I0581978f
* changes: Limit transcoding size workaround to windows Workaround to fixup MTP transcode file size
This commit is contained in:
commit
06c8be69b9
@ -103,6 +103,7 @@ public class MtpDatabase implements AutoCloseable {
|
||||
private int mDeviceType;
|
||||
private String mHostType;
|
||||
private boolean mSkipThumbForHost = false;
|
||||
private volatile boolean mHostIsWindows = false;
|
||||
|
||||
private MtpServer mServer;
|
||||
private MtpStorageManager mManager;
|
||||
@ -358,7 +359,7 @@ public class MtpDatabase implements AutoCloseable {
|
||||
}
|
||||
|
||||
public void addStorage(StorageVolume storage) {
|
||||
MtpStorage mtpStorage = mManager.addMtpStorage(storage);
|
||||
MtpStorage mtpStorage = mManager.addMtpStorage(storage, () -> mHostIsWindows);
|
||||
mStorageMap.put(storage.getPath(), mtpStorage);
|
||||
if (mServer != null) {
|
||||
mServer.addStorage(mtpStorage);
|
||||
@ -413,6 +414,7 @@ public class MtpDatabase implements AutoCloseable {
|
||||
}
|
||||
mHostType = "";
|
||||
mSkipThumbForHost = false;
|
||||
mHostIsWindows = false;
|
||||
}
|
||||
|
||||
@VisibleForNative
|
||||
@ -736,10 +738,12 @@ public class MtpDatabase implements AutoCloseable {
|
||||
: MtpConstants.RESPONSE_GENERAL_ERROR);
|
||||
case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO:
|
||||
mHostType = stringValue;
|
||||
Log.d(TAG, "setDeviceProperty." + Integer.toHexString(property)
|
||||
+ "=" + stringValue);
|
||||
if (stringValue.startsWith("Android/")) {
|
||||
Log.d(TAG, "setDeviceProperty." + Integer.toHexString(property)
|
||||
+ "=" + stringValue);
|
||||
mSkipThumbForHost = true;
|
||||
} else if (stringValue.startsWith("Windows/")) {
|
||||
mHostIsWindows = true;
|
||||
}
|
||||
return MtpConstants.RESPONSE_OK;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package android.mtp;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.storage.StorageVolume;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* This class represents a storage unit on an MTP device.
|
||||
* Used only for MTP support in USB responder mode.
|
||||
@ -33,14 +35,16 @@ public class MtpStorage {
|
||||
private final boolean mRemovable;
|
||||
private final long mMaxFileSize;
|
||||
private final String mVolumeName;
|
||||
private final Supplier<Boolean> mIsHostWindows;
|
||||
|
||||
public MtpStorage(StorageVolume volume, int storageId) {
|
||||
public MtpStorage(StorageVolume volume, int storageId, Supplier<Boolean> isHostWindows) {
|
||||
mStorageId = storageId;
|
||||
mPath = volume.getPath();
|
||||
mDescription = volume.getDescription(null);
|
||||
mRemovable = volume.isRemovable();
|
||||
mMaxFileSize = volume.getMaxFileSize();
|
||||
mVolumeName = volume.getMediaStoreVolumeName();
|
||||
mIsHostWindows = isHostWindows;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,4 +97,13 @@ public class MtpStorage {
|
||||
public String getVolumeName() {
|
||||
return mVolumeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the mtp host of this storage is Windows.
|
||||
*
|
||||
* @return is host Windows
|
||||
*/
|
||||
public boolean isHostWindows() {
|
||||
return mIsHostWindows.get();
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,11 @@ package android.mtp;
|
||||
|
||||
import android.media.MediaFile;
|
||||
import android.os.FileObserver;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.storage.StorageVolume;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.StructStat;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
@ -35,6 +39,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* MtpStorageManager provides functionality for listing, tracking, and notifying MtpServer of
|
||||
@ -199,7 +204,38 @@ public class MtpStorageManager {
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return mIsDir ? 0 : getPath().toFile().length();
|
||||
return mIsDir ? 0 : maybeApplyTranscodeLengthWorkaround(getPath().toFile().length());
|
||||
}
|
||||
|
||||
private long maybeApplyTranscodeLengthWorkaround(long length) {
|
||||
// Windows truncates transferred files to the size advertised in the object property.
|
||||
if (mStorage.isHostWindows() && isTranscodeMtpEnabled() && isFileTranscodeSupported()) {
|
||||
// If the file supports transcoding, we double the returned size to accommodate
|
||||
// the increase in size from transcoding to AVC. This is the same heuristic
|
||||
// applied in the FUSE daemon (MediaProvider).
|
||||
return length * 2;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
private boolean isTranscodeMtpEnabled() {
|
||||
return SystemProperties.getBoolean("sys.fuse.transcode_mtp", false);
|
||||
}
|
||||
|
||||
private boolean isFileTranscodeSupported() {
|
||||
// Check if the file supports transcoding by reading the |st_nlinks| struct stat
|
||||
// field. This will be > 1 if the file supports transcoding. The FUSE daemon
|
||||
// sets the field accordingly to enable the MTP stack workaround some Windows OS
|
||||
// MTP client bug where they ignore the size returned as part of getting the MTP
|
||||
// object, see MtpServer#doGetObject.
|
||||
final Path path = getPath();
|
||||
try {
|
||||
StructStat stat = Os.stat(path.toString());
|
||||
return stat.st_nlink > 1;
|
||||
} catch (ErrnoException e) {
|
||||
Log.w(TAG, "Failed to stat path: " + getPath() + ". Ignoring transcoding.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
@ -420,10 +456,12 @@ public class MtpStorageManager {
|
||||
* @param volume Storage to add.
|
||||
* @return the associated MtpStorage
|
||||
*/
|
||||
public synchronized MtpStorage addMtpStorage(StorageVolume volume) {
|
||||
public synchronized MtpStorage addMtpStorage(StorageVolume volume,
|
||||
Supplier<Boolean> isHostWindows) {
|
||||
int storageId = ((getNextStorageId() & 0x0000FFFF) << 16) + 1;
|
||||
MtpStorage storage = new MtpStorage(volume, storageId);
|
||||
MtpObject root = new MtpObject(storage.getPath(), storageId, storage, null, true);
|
||||
MtpStorage storage = new MtpStorage(volume, storageId, isHostWindows);
|
||||
MtpObject root = new MtpObject(storage.getPath(), storageId, storage, /* parent= */ null,
|
||||
/* isDir= */ true);
|
||||
mRoots.put(storageId, root);
|
||||
return storage;
|
||||
}
|
||||
|
@ -159,10 +159,11 @@ public class MtpStorageManagerTest {
|
||||
Log.d(TAG, "sendObjectInfoChanged: " + id);
|
||||
objectsInfoChanged.add(id);
|
||||
}
|
||||
}, null);
|
||||
}, /* subdirectories= */ null);
|
||||
|
||||
mainMtpStorage = manager.addMtpStorage(mainStorage);
|
||||
secondaryMtpStorage = manager.addMtpStorage(secondaryStorage);
|
||||
mainMtpStorage = manager.addMtpStorage(mainStorage, /* isHostWindows= */ () -> false);
|
||||
secondaryMtpStorage = manager.addMtpStorage(secondaryStorage,
|
||||
/* isHostWindows= */ () -> false);
|
||||
}
|
||||
|
||||
@After
|
||||
|
Loading…
x
Reference in New Issue
Block a user