Fields Summary |
---|
private static final Pattern | sApkPatternPattern to find filenames that match "*.apk" |
private static final String | PM_FULL_LISTING |
private static final Pattern | sPmPatternPattern to parse the output of the 'pm -lf' command.
The output format looks like:
/data/app/myapp.apk=com.mypackage.myapp |
public static final String | DIRECTORY_DATATop level data folder. |
public static final String | DIRECTORY_SDCARDTop level sdcard folder. |
public static final String | DIRECTORY_SYSTEMTop level system folder. |
public static final String | DIRECTORY_TEMPTop level temp folder. |
public static final String | DIRECTORY_APPApplication folder. |
private static final String[] | sRootLevelApprovedItems |
public static final long | REFRESH_RATE |
static final long | REFRESH_TESTRefresh test has to be slightly lower for precision issue. |
public static final int | TYPE_FILEEntry type: File |
public static final int | TYPE_DIRECTORYEntry type: Directory |
public static final int | TYPE_DIRECTORY_LINKEntry type: Directory Link |
public static final int | TYPE_BLOCKEntry type: Block |
public static final int | TYPE_CHARACTEREntry type: Character |
public static final int | TYPE_LINKEntry type: Link |
public static final int | TYPE_SOCKETEntry type: Socket |
public static final int | TYPE_FIFOEntry type: FIFO |
public static final int | TYPE_OTHEREntry type: Other |
public static final String | FILE_SEPARATORDevice side file separator. |
private static final String | FILE_ROOT |
private static Pattern | sLsPatternRegexp pattern to parse the result from ls. |
private Device | mDevice |
private FileEntry | mRoot |
private ArrayList | mThreadList |
Methods Summary |
---|
private void | doLs(com.android.ddmlib.FileListingService$FileEntry entry)
// create a list that will receive the list of the entries
ArrayList<FileEntry> entryList = new ArrayList<FileEntry>();
// create a list that will receive the link to compute post ls;
ArrayList<String> linkList = new ArrayList<String>();
try {
// create the command
String command = "ls -l " + entry.getFullPath(); //$NON-NLS-1$
// create the receiver object that will parse the result from ls
LsReceiver receiver = new LsReceiver(entry, entryList, linkList);
// call ls.
mDevice.executeShellCommand(command, receiver);
// finish the process of the receiver to handle links
receiver.finishLinks();
} catch (IOException e) {
}
// at this point we need to refresh the viewer
entry.fetchTime = System.currentTimeMillis();
// sort the children and set them as the new children
Collections.sort(entryList, FileEntry.sEntryComparator);
entry.setChildren(entryList);
|
public com.android.ddmlib.FileListingService$FileEntry[] | getChildren(com.android.ddmlib.FileListingService$FileEntry entry, boolean useCache, com.android.ddmlib.FileListingService$IListingReceiver receiver)Returns the children of a {@link FileEntry}.
This method supports a cache mechanism and synchronous and asynchronous modes.
If receiver is null , the device side ls
command is done synchronously, and the method will return upon completion of the command.
If receiver is non null , the command is launched is a separate
thread and upon completion, the receiver will be notified of the result.
The result for each ls command is cached in the parent
FileEntry . useCache allows usage of this cache, but only if the
cache is valid. The cache is valid only for {@link FileListingService#REFRESH_RATE} ms.
After that a new ls command is always executed.
If the cache is valid and useCache == true , the method will always simply
return the value of the cache, whether a {@link IListingReceiver} has been provided or not.
// first thing we do is check the cache, and if we already have a recent
// enough children list, we just return that.
if (useCache && entry.needFetch() == false) {
return entry.getCachedChildren();
}
// if there's no receiver, then this is a synchronous call, and we
// return the result of ls
if (receiver == null) {
doLs(entry);
return entry.getCachedChildren();
}
// this is a asynchronous call.
// we launch a thread that will do ls and give the listing
// to the receiver
Thread t = new Thread("ls " + entry.getFullPath()) { //$NON-NLS-1$
@Override
public void run() {
doLs(entry);
receiver.setChildren(entry, entry.getCachedChildren());
final FileEntry[] children = entry.getCachedChildren();
if (children.length > 0 && children[0].isApplicationPackage()) {
final HashMap<String, FileEntry> map = new HashMap<String, FileEntry>();
for (FileEntry child : children) {
String path = child.getFullPath();
map.put(path, child);
}
// call pm.
String command = PM_FULL_LISTING;
try {
mDevice.executeShellCommand(command, new MultiLineReceiver() {
@Override
public void processNewLines(String[] lines) {
for (String line : lines) {
if (line.length() > 0) {
// get the filepath and package from the line
Matcher m = sPmPattern.matcher(line);
if (m.matches()) {
// get the children with that path
FileEntry entry = map.get(m.group(1));
if (entry != null) {
entry.info = m.group(2);
receiver.refreshEntry(entry);
}
}
}
}
}
public boolean isCancelled() {
return false;
}
});
} catch (IOException e) {
// adb failed somehow, we do nothing.
}
}
// if another thread is pending, launch it
synchronized (mThreadList) {
// first remove ourselves from the list
mThreadList.remove(this);
// then launch the next one if applicable.
if (mThreadList.size() > 0) {
Thread t = mThreadList.get(0);
t.start();
}
}
}
};
// we don't want to run multiple ls on the device at the same time, so we
// store the thread in a list and launch it only if there's no other thread running.
// the thread will launch the next one once it's done.
synchronized (mThreadList) {
// add to the list
mThreadList.add(t);
// if it's the only one, launch it.
if (mThreadList.size() == 1) {
t.start();
}
}
// and we return null.
return null;
|
public com.android.ddmlib.FileListingService$FileEntry | getRoot()Returns the root element.
if (mDevice != null) {
if (mRoot == null) {
mRoot = new FileEntry(null /* parent */, "" /* name */, TYPE_DIRECTORY,
true /* isRoot */);
}
return mRoot;
}
return null;
|