Loading media/java/android/mtp/MtpDatabase.java +25 −18 Original line number Diff line number Diff line Loading @@ -52,11 +52,10 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; import java.util.stream.Stream; /** * MtpDatabase provides an interface for MTP operations that MtpServer can use. To do this, it uses Loading Loading @@ -453,21 +452,25 @@ public class MtpDatabase implements AutoCloseable { } private int[] getObjectList(int storageID, int format, int parent) { Stream<MtpStorageManager.MtpObject> objectStream = mManager.getObjects(parent, List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); if (objectStream == null) { if (objs == null) { return null; } return objectStream.mapToInt(MtpStorageManager.MtpObject::getId).toArray(); int[] ret = new int[objs.size()]; for (int i = 0; i < objs.size(); i++) { ret[i] = objs.get(i).getId(); } return ret; } private int getNumObjects(int storageID, int format, int parent) { Stream<MtpStorageManager.MtpObject> objectStream = mManager.getObjects(parent, List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); if (objectStream == null) { if (objs == null) { return -1; } return (int) objectStream.count(); return objs.size(); } private MtpPropertyList getObjectPropertyList(int handle, int format, int property, Loading @@ -489,11 +492,12 @@ public class MtpDatabase implements AutoCloseable { // depth 0: single object, depth 1: immediate children return new MtpPropertyList(MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED); } Stream<MtpStorageManager.MtpObject> objectStream = Stream.of(); List<MtpStorageManager.MtpObject> objs = null; MtpStorageManager.MtpObject thisObj = null; if (handle == 0xFFFFFFFF) { // All objects are requested objectStream = mManager.getObjects(0, format, 0xFFFFFFFF); if (objectStream == null) { objs = mManager.getObjects(0, format, 0xFFFFFFFF); if (objs == null) { return new MtpPropertyList(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE); } } else if (handle != 0) { Loading @@ -503,7 +507,7 @@ public class MtpDatabase implements AutoCloseable { return new MtpPropertyList(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE); } if (obj.getFormat() == format || format == 0) { objectStream = Stream.of(obj); thisObj = obj; } } if (handle == 0 || depth == 1) { Loading @@ -511,19 +515,22 @@ public class MtpDatabase implements AutoCloseable { handle = 0xFFFFFFFF; } // Get the direct children of root or this object. Stream<MtpStorageManager.MtpObject> childStream = mManager.getObjects(handle, format, objs = mManager.getObjects(handle, format, 0xFFFFFFFF); if (childStream == null) { if (objs == null) { return new MtpPropertyList(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE); } objectStream = Stream.concat(objectStream, childStream); } if (objs == null) { objs = new ArrayList<>(); } if (thisObj != null) { objs.add(thisObj); } MtpPropertyList ret = new MtpPropertyList(MtpConstants.RESPONSE_OK); MtpPropertyGroup propertyGroup; Iterator<MtpStorageManager.MtpObject> iter = objectStream.iterator(); while (iter.hasNext()) { MtpStorageManager.MtpObject obj = iter.next(); for (MtpStorageManager.MtpObject obj : objs) { if (property == 0xffffffff) { // Get all properties supported by this object propertyGroup = mPropertyGroupsByFormat.get(obj.getFormat()); Loading media/java/android/mtp/MtpStorageManager.java +28 −32 Original line number Diff line number Diff line Loading @@ -31,10 +31,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Objects; import java.util.List; import java.util.Set; import java.util.stream.Stream; /** * MtpStorageManager provides functionality for listing, tracking, and notifying MtpServer of Loading Loading @@ -358,13 +356,13 @@ public class MtpStorageManager { * Clean up resources used by the storage manager. */ public synchronized void close() { Stream<MtpObject> objs = Stream.concat(mRoots.values().stream(), mObjects.values().stream()); Iterator<MtpObject> iter = objs.iterator(); while (iter.hasNext()) { // Close all FileObservers. MtpObject obj = iter.next(); for (MtpObject obj : mObjects.values()) { if (obj.getObserver() != null) { obj.getObserver().stopWatching(); obj.setObserver(null); } } for (MtpObject obj : mRoots.values()) { if (obj.getObserver() != null) { obj.getObserver().stopWatching(); obj.setObserver(null); Loading Loading @@ -495,49 +493,48 @@ public class MtpStorageManager { * @param parent object id of the parent. 0 for all objects, 0xFFFFFFFF for all object in root * @param format format of returned objects. 0 for any format * @param storageId storage id to look in. 0xFFFFFFFF for all storages * @return A stream of matched objects, or null if error * @return A list of matched objects, or null if error */ public synchronized Stream<MtpObject> getObjects(int parent, int format, int storageId) { public synchronized List<MtpObject> getObjects(int parent, int format, int storageId) { boolean recursive = parent == 0; ArrayList<MtpObject> objs = new ArrayList<>(); boolean ret = true; if (parent == 0xFFFFFFFF) parent = 0; if (storageId == 0xFFFFFFFF) { // query all stores if (parent == 0) { // Get the objects of this format and parent in each store. ArrayList<Stream<MtpObject>> streamList = new ArrayList<>(); for (MtpObject root : mRoots.values()) { streamList.add(getObjects(root, format, recursive)); ret &= getObjects(objs, root, format, recursive); } return Stream.of(streamList).flatMap(Collection::stream).reduce(Stream::concat) .orElseGet(Stream::empty); return ret ? objs : null; } } MtpObject obj = parent == 0 ? getStorageRoot(storageId) : getObject(parent); if (obj == null) return null; return getObjects(obj, format, recursive); ret = getObjects(objs, obj, format, recursive); return ret ? objs : null; } private synchronized Stream<MtpObject> getObjects(MtpObject parent, int format, boolean rec) { private synchronized boolean getObjects(List<MtpObject> toAdd, MtpObject parent, int format, boolean rec) { Collection<MtpObject> children = getChildren(parent); if (children == null) return null; Stream<MtpObject> ret = Stream.of(children).flatMap(Collection::stream); return false; if (format != 0) { ret = ret.filter(o -> o.getFormat() == format); for (MtpObject o : children) { if (format == 0 || o.getFormat() == format) { toAdd.add(o); } } boolean ret = true; if (rec) { // Get all objects recursively. ArrayList<Stream<MtpObject>> streamList = new ArrayList<>(); streamList.add(ret); for (MtpObject o : children) { if (o.isDir()) streamList.add(getObjects(o, format, true)); ret &= getObjects(toAdd, o, format, true); } ret = Stream.of(streamList).filter(Objects::nonNull).flatMap(Collection::stream) .reduce(Stream::concat).orElseGet(Stream::empty); } return ret; } Loading Loading @@ -767,12 +764,11 @@ public class MtpStorageManager { * @return true iff cache is consistent */ public synchronized boolean checkConsistency() { Stream<MtpObject> objs = Stream.concat(mRoots.values().stream(), mObjects.values().stream()); Iterator<MtpObject> iter = objs.iterator(); List<MtpObject> objs = new ArrayList<>(); objs.addAll(mRoots.values()); objs.addAll(mObjects.values()); boolean ret = true; while (iter.hasNext()) { MtpObject obj = iter.next(); for (MtpObject obj : objs) { if (!obj.exists()) { Log.w(TAG, "Object doesn't exist " + obj.getPath() + " " + obj.getId()); ret = false; Loading media/tests/MtpTests/src/android/mtp/MtpStorageManagerTest.java +110 −110 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
media/java/android/mtp/MtpDatabase.java +25 −18 Original line number Diff line number Diff line Loading @@ -52,11 +52,10 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; import java.util.stream.Stream; /** * MtpDatabase provides an interface for MTP operations that MtpServer can use. To do this, it uses Loading Loading @@ -453,21 +452,25 @@ public class MtpDatabase implements AutoCloseable { } private int[] getObjectList(int storageID, int format, int parent) { Stream<MtpStorageManager.MtpObject> objectStream = mManager.getObjects(parent, List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); if (objectStream == null) { if (objs == null) { return null; } return objectStream.mapToInt(MtpStorageManager.MtpObject::getId).toArray(); int[] ret = new int[objs.size()]; for (int i = 0; i < objs.size(); i++) { ret[i] = objs.get(i).getId(); } return ret; } private int getNumObjects(int storageID, int format, int parent) { Stream<MtpStorageManager.MtpObject> objectStream = mManager.getObjects(parent, List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent, format, storageID); if (objectStream == null) { if (objs == null) { return -1; } return (int) objectStream.count(); return objs.size(); } private MtpPropertyList getObjectPropertyList(int handle, int format, int property, Loading @@ -489,11 +492,12 @@ public class MtpDatabase implements AutoCloseable { // depth 0: single object, depth 1: immediate children return new MtpPropertyList(MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED); } Stream<MtpStorageManager.MtpObject> objectStream = Stream.of(); List<MtpStorageManager.MtpObject> objs = null; MtpStorageManager.MtpObject thisObj = null; if (handle == 0xFFFFFFFF) { // All objects are requested objectStream = mManager.getObjects(0, format, 0xFFFFFFFF); if (objectStream == null) { objs = mManager.getObjects(0, format, 0xFFFFFFFF); if (objs == null) { return new MtpPropertyList(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE); } } else if (handle != 0) { Loading @@ -503,7 +507,7 @@ public class MtpDatabase implements AutoCloseable { return new MtpPropertyList(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE); } if (obj.getFormat() == format || format == 0) { objectStream = Stream.of(obj); thisObj = obj; } } if (handle == 0 || depth == 1) { Loading @@ -511,19 +515,22 @@ public class MtpDatabase implements AutoCloseable { handle = 0xFFFFFFFF; } // Get the direct children of root or this object. Stream<MtpStorageManager.MtpObject> childStream = mManager.getObjects(handle, format, objs = mManager.getObjects(handle, format, 0xFFFFFFFF); if (childStream == null) { if (objs == null) { return new MtpPropertyList(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE); } objectStream = Stream.concat(objectStream, childStream); } if (objs == null) { objs = new ArrayList<>(); } if (thisObj != null) { objs.add(thisObj); } MtpPropertyList ret = new MtpPropertyList(MtpConstants.RESPONSE_OK); MtpPropertyGroup propertyGroup; Iterator<MtpStorageManager.MtpObject> iter = objectStream.iterator(); while (iter.hasNext()) { MtpStorageManager.MtpObject obj = iter.next(); for (MtpStorageManager.MtpObject obj : objs) { if (property == 0xffffffff) { // Get all properties supported by this object propertyGroup = mPropertyGroupsByFormat.get(obj.getFormat()); Loading
media/java/android/mtp/MtpStorageManager.java +28 −32 Original line number Diff line number Diff line Loading @@ -31,10 +31,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Objects; import java.util.List; import java.util.Set; import java.util.stream.Stream; /** * MtpStorageManager provides functionality for listing, tracking, and notifying MtpServer of Loading Loading @@ -358,13 +356,13 @@ public class MtpStorageManager { * Clean up resources used by the storage manager. */ public synchronized void close() { Stream<MtpObject> objs = Stream.concat(mRoots.values().stream(), mObjects.values().stream()); Iterator<MtpObject> iter = objs.iterator(); while (iter.hasNext()) { // Close all FileObservers. MtpObject obj = iter.next(); for (MtpObject obj : mObjects.values()) { if (obj.getObserver() != null) { obj.getObserver().stopWatching(); obj.setObserver(null); } } for (MtpObject obj : mRoots.values()) { if (obj.getObserver() != null) { obj.getObserver().stopWatching(); obj.setObserver(null); Loading Loading @@ -495,49 +493,48 @@ public class MtpStorageManager { * @param parent object id of the parent. 0 for all objects, 0xFFFFFFFF for all object in root * @param format format of returned objects. 0 for any format * @param storageId storage id to look in. 0xFFFFFFFF for all storages * @return A stream of matched objects, or null if error * @return A list of matched objects, or null if error */ public synchronized Stream<MtpObject> getObjects(int parent, int format, int storageId) { public synchronized List<MtpObject> getObjects(int parent, int format, int storageId) { boolean recursive = parent == 0; ArrayList<MtpObject> objs = new ArrayList<>(); boolean ret = true; if (parent == 0xFFFFFFFF) parent = 0; if (storageId == 0xFFFFFFFF) { // query all stores if (parent == 0) { // Get the objects of this format and parent in each store. ArrayList<Stream<MtpObject>> streamList = new ArrayList<>(); for (MtpObject root : mRoots.values()) { streamList.add(getObjects(root, format, recursive)); ret &= getObjects(objs, root, format, recursive); } return Stream.of(streamList).flatMap(Collection::stream).reduce(Stream::concat) .orElseGet(Stream::empty); return ret ? objs : null; } } MtpObject obj = parent == 0 ? getStorageRoot(storageId) : getObject(parent); if (obj == null) return null; return getObjects(obj, format, recursive); ret = getObjects(objs, obj, format, recursive); return ret ? objs : null; } private synchronized Stream<MtpObject> getObjects(MtpObject parent, int format, boolean rec) { private synchronized boolean getObjects(List<MtpObject> toAdd, MtpObject parent, int format, boolean rec) { Collection<MtpObject> children = getChildren(parent); if (children == null) return null; Stream<MtpObject> ret = Stream.of(children).flatMap(Collection::stream); return false; if (format != 0) { ret = ret.filter(o -> o.getFormat() == format); for (MtpObject o : children) { if (format == 0 || o.getFormat() == format) { toAdd.add(o); } } boolean ret = true; if (rec) { // Get all objects recursively. ArrayList<Stream<MtpObject>> streamList = new ArrayList<>(); streamList.add(ret); for (MtpObject o : children) { if (o.isDir()) streamList.add(getObjects(o, format, true)); ret &= getObjects(toAdd, o, format, true); } ret = Stream.of(streamList).filter(Objects::nonNull).flatMap(Collection::stream) .reduce(Stream::concat).orElseGet(Stream::empty); } return ret; } Loading Loading @@ -767,12 +764,11 @@ public class MtpStorageManager { * @return true iff cache is consistent */ public synchronized boolean checkConsistency() { Stream<MtpObject> objs = Stream.concat(mRoots.values().stream(), mObjects.values().stream()); Iterator<MtpObject> iter = objs.iterator(); List<MtpObject> objs = new ArrayList<>(); objs.addAll(mRoots.values()); objs.addAll(mObjects.values()); boolean ret = true; while (iter.hasNext()) { MtpObject obj = iter.next(); for (MtpObject obj : objs) { if (!obj.exists()) { Log.w(TAG, "Object doesn't exist " + obj.getPath() + " " + obj.getId()); ret = false; Loading
media/tests/MtpTests/src/android/mtp/MtpStorageManagerTest.java +110 −110 File changed.Preview size limit exceeded, changes collapsed. Show changes