Enqueues chunks of data (from various sources – application crashes, kernel log records, etc.). The queue is size bounded and will drop old data if the enqueued data exceeds the maximum size. You can think of this as a persistent, system-wide, blob-oriented “logcat”.
publicvoidhandleApplicationStrictModeViolation(IBinderapp,intviolationMask,StrictMode.ViolationInfoinfo){ProcessRecordr=findAppProcess(app,"StrictMode");if(r==null){return;}if((violationMask&StrictMode.PENALTY_DROPBOX)!=0){IntegerstackFingerprint=info.hashCode();booleanlogIt=true;synchronized(mAlreadyLoggedViolatedStacks){if(mAlreadyLoggedViolatedStacks.contains(stackFingerprint)){logIt=false;// TODO: sub-sample into EventLog for these, with// the info.durationMillis? Then we'd get// the relative pain numbers, without logging all// the stack traces repeatedly. We'd want to do// likewise in the client code, which also does// dup suppression, before the Binder call.}else{if(mAlreadyLoggedViolatedStacks.size()>=MAX_DUP_SUPPRESSED_STACKS){mAlreadyLoggedViolatedStacks.clear();}mAlreadyLoggedViolatedStacks.add(stackFingerprint);}}if(logIt){logStrictModeViolationToDropBox(r,info);}}//......}
/** This class calls its monitor every minute. Killing this process if they don't return **/publicclassWatchdogextendsThread{//......@Overridepublicvoidrun(){booleanwaitedHalf=false;while(true){//......// If we got here, that means that the system is most likely hung.// First collect stack traces from all threads of the system process.// Then kill this process so that the system will restart.//......// Try to add the error to the dropbox, but assuming that the ActivityManager// itself may be deadlocked. (which has happened, causing this statement to// deadlock and the watchdog as a whole to be ineffective)ThreaddropboxThread=newThread("watchdogWriteToDropbox"){publicvoidrun(){mActivity.addErrorToDropBox("watchdog",null,"system_server",null,null,name,null,stack,null);}};dropboxThread.start();try{dropboxThread.join(2000);// wait up to 2 seconds for it to return.}catch(InterruptedExceptionignored){}//......}}//......}
privatevoidlogBootEvents(Contextctx)throwsIOException{finalDropBoxManagerdb=(DropBoxManager)ctx.getSystemService(Context.DROPBOX_SERVICE);finalSharedPreferencesprefs=ctx.getSharedPreferences("log_files",Context.MODE_PRIVATE);finalStringheaders=newStringBuilder(512).append("Build: ").append(Build.FINGERPRINT).append("\n").append("Hardware: ").append(Build.BOARD).append("\n").append("Revision: ").append(SystemProperties.get("ro.revision","")).append("\n").append("Bootloader: ").append(Build.BOOTLOADER).append("\n").append("Radio: ").append(Build.RADIO).append("\n").append("Kernel: ").append(FileUtils.readTextFile(newFile("/proc/version"),1024,"...\n")).append("\n").toString();Stringrecovery=RecoverySystem.handleAftermath();if(recovery!=null&&db!=null){db.addText("SYSTEM_RECOVERY_LOG",headers+recovery);}if(SystemProperties.getLong("ro.runtime.firstboot",0)==0){Stringnow=Long.toString(System.currentTimeMillis());SystemProperties.set("ro.runtime.firstboot",now);if(db!=null)db.addText("SYSTEM_BOOT",headers);// Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())addFileToDropBox(db,prefs,headers,"/proc/last_kmsg",-LOG_SIZE,"SYSTEM_LAST_KMSG");addFileToDropBox(db,prefs,headers,"/cache/recovery/log",-LOG_SIZE,"SYSTEM_RECOVERY_LOG");addFileToDropBox(db,prefs,headers,"/data/dontpanic/apanic_console",-LOG_SIZE,"APANIC_CONSOLE");addFileToDropBox(db,prefs,headers,"/data/dontpanic/apanic_threads",-LOG_SIZE,"APANIC_THREADS");}else{if(db!=null)db.addText("SYSTEM_RESTART",headers);}// Scan existing tombstones (in case any new ones appeared)File[]tombstoneFiles=TOMBSTONE_DIR.listFiles();for(inti=0;tombstoneFiles!=null&&i<tombstoneFiles.length;i++){addFileToDropBox(db,prefs,headers,tombstoneFiles[i].getPath(),LOG_SIZE,"SYSTEM_TOMBSTONE");}// Start watching for new tombstone files; will record them as they occur.// This gets registered with the singleton file observer thread.sTombstoneObserver=newFileObserver(TOMBSTONE_DIR.getPath(),FileObserver.CLOSE_WRITE){@OverridepublicvoidonEvent(intevent,Stringpath){try{Stringfilename=newFile(TOMBSTONE_DIR,path).getPath();addFileToDropBox(db,prefs,headers,filename,LOG_SIZE,"SYSTEM_TOMBSTONE");}catch(IOExceptione){Slog.e(TAG,"Can't log tombstone",e);}}};sTombstoneObserver.startWatching();}