public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { pw.println("Permission Denial: Can't dump DropBoxManagerService"); return; } try { init(); } catch (IOException e) { pw.println("Can't initialize: " + e); Slog.e(TAG, "Can't init", e); return; } if (PROFILE_DUMP) Debug.startMethodTracing("/data/trace/dropbox.dump"); StringBuilder out = new StringBuilder(); boolean doPrint = false, doFile = false; ArrayList<String> searchArgs = new ArrayList<String>(); for (int i = 0; args != null && i < args.length; i++) { if (args[i].equals("-p") || args[i].equals("--print")) { doPrint = true; } else if (args[i].equals("-f") || args[i].equals("--file")) { doFile = true; } else if (args[i].startsWith("-")) { out.append("Unknown argument: ").append(args[i]).append("\n"); } else { searchArgs.add(args[i]); } } out.append("Drop box contents: ").append(mAllFiles.contents.size()).append(" entries\n"); if (!searchArgs.isEmpty()) { out.append("Searching for:"); for (String a : searchArgs) out.append(" ").append(a); out.append("\n"); } int numFound = 0, numArgs = searchArgs.size(); Time time = new Time(); out.append("\n"); for (EntryFile entry : mAllFiles.contents) { time.set(entry.timestampMillis); String date = time.format("%Y-%m-%d %H:%M:%S"); boolean match = true; for (int i = 0; i < numArgs && match; i++) { String arg = searchArgs.get(i); match = (date.contains(arg) || arg.equals(entry.tag)); } if (!match) continue; numFound++; if (doPrint) out.append("========================================\n"); out.append(date).append(" ").append(entry.tag == null ? "(no tag)" : entry.tag); if (entry.file == null) { out.append(" (no file)\n"); continue; } else if ((entry.flags & DropBoxManager.IS_EMPTY) != 0) { out.append(" (contents lost)\n"); continue; } else { out.append(" ("); if ((entry.flags & DropBoxManager.IS_GZIPPED) != 0) out.append("compressed "); out.append((entry.flags & DropBoxManager.IS_TEXT) != 0 ? "text" : "data"); out.append(", ").append(entry.file.length()).append(" bytes)\n"); } if (doFile || (doPrint && (entry.flags & DropBoxManager.IS_TEXT) == 0)) { if (!doPrint) out.append(" "); out.append(entry.file.getPath()).append("\n"); } if ((entry.flags & DropBoxManager.IS_TEXT) != 0 && (doPrint || !doFile)) { DropBoxManager.Entry dbe = null; InputStreamReader isr = null; try { dbe = new DropBoxManager.Entry(entry.tag, entry.timestampMillis, entry.file, entry.flags); if (doPrint) { isr = new InputStreamReader(dbe.getInputStream()); char[] buf = new char[4096]; boolean newline = false; for (; ; ) { int n = isr.read(buf); if (n <= 0) break; out.append(buf, 0, n); newline = (buf[n - 1] == '\n'); // Flush periodically when printing to avoid out-of-memory. if (out.length() > 65536) { pw.write(out.toString()); out.setLength(0); } } if (!newline) out.append("\n"); } else { String text = dbe.getText(70); out.append(" "); if (text == null) { out.append("[null]"); } else { boolean truncated = (text.length() == 70); out.append(text.trim().replace('\n', '/')); if (truncated) out.append(" ..."); } out.append("\n"); } } catch (IOException e) { out.append("*** ").append(e.toString()).append("\n"); Slog.e(TAG, "Can't read: " + entry.file, e); } finally { if (dbe != null) dbe.close(); if (isr != null) { try { isr.close(); } catch (IOException unused) { } } } } if (doPrint) out.append("\n"); } if (numFound == 0) out.append("(No entries found.)\n"); if (args == null || args.length == 0) { if (!doPrint) out.append("\n"); out.append("Usage: dumpsys dropbox [--print|--file] [YYYY-mm-dd] [HH:MM:SS] [tag]\n"); } pw.write(out.toString()); if (PROFILE_DUMP) Debug.stopMethodTracing(); }
@Override public void add(DropBoxManager.Entry entry) { File temp = null; OutputStream output = null; final String tag = entry.getTag(); try { int flags = entry.getFlags(); if ((flags & DropBoxManager.IS_EMPTY) != 0) throw new IllegalArgumentException(); init(); if (!isTagEnabled(tag)) return; long max = trimToFit(); long lastTrim = System.currentTimeMillis(); byte[] buffer = new byte[mBlockSize]; InputStream input = entry.getInputStream(); // First, accumulate up to one block worth of data in memory before // deciding whether to compress the data or not. int read = 0; while (read < buffer.length) { int n = input.read(buffer, read, buffer.length - read); if (n <= 0) break; read += n; } // If we have at least one block, compress it -- otherwise, just write // the data in uncompressed form. temp = new File(mDropBoxDir, "drop" + Thread.currentThread().getId() + ".tmp"); int bufferSize = mBlockSize; if (bufferSize > 4096) bufferSize = 4096; if (bufferSize < 512) bufferSize = 512; FileOutputStream foutput = new FileOutputStream(temp); output = new BufferedOutputStream(foutput, bufferSize); if (read == buffer.length && ((flags & DropBoxManager.IS_GZIPPED) == 0)) { output = new GZIPOutputStream(output); flags = flags | DropBoxManager.IS_GZIPPED; } do { output.write(buffer, 0, read); long now = System.currentTimeMillis(); if (now - lastTrim > 30 * 1000) { max = trimToFit(); // In case data dribbles in slowly lastTrim = now; } read = input.read(buffer); if (read <= 0) { FileUtils.sync(foutput); output.close(); // Get a final size measurement output = null; } else { output.flush(); // So the size measurement is pseudo-reasonable } long len = temp.length(); if (len > max) { Slog.w(TAG, "Dropping: " + tag + " (" + temp.length() + " > " + max + " bytes)"); temp.delete(); temp = null; // Pass temp = null to createEntry() to leave a tombstone break; } } while (read > 0); long time = createEntry(temp, tag, flags); temp = null; final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED); dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag); dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time); if (!mBooted) { dropboxIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } // Call sendBroadcast after returning from this call to avoid deadlock. In particular // the caller may be holding the WindowManagerService lock but sendBroadcast requires a // lock in ActivityManagerService. ActivityManagerService has been caught holding that // very lock while waiting for the WindowManagerService lock. mHandler.sendMessage(mHandler.obtainMessage(MSG_SEND_BROADCAST, dropboxIntent)); } catch (IOException e) { Slog.e(TAG, "Can't write: " + tag, e); } finally { try { if (output != null) output.close(); } catch (IOException e) { } entry.close(); if (temp != null) temp.delete(); } }