|
21 | 21 | import android.content.pm.ApplicationInfo; |
22 | 22 | import android.content.pm.PackageManager; |
23 | 23 | import android.os.Build; |
| 24 | +import android.os.SystemClock; |
24 | 25 |
|
25 | 26 | import java.io.File; |
| 27 | +import java.io.FilenameFilter; |
26 | 28 | import java.util.ArrayList; |
27 | 29 | import java.util.List; |
28 | 30 | import java.util.Locale; |
@@ -247,6 +249,69 @@ public static List<String> getLaunchScript(Context context, Class<?> clazz, Stri |
247 | 249 | return script; |
248 | 250 | } |
249 | 251 |
|
| 252 | + /** Prefixes of filename to remove from the app's cache directory */ |
| 253 | + public static final String[] CLEANUP_CACHE_PREFIXES = new String[] { ".app_process32_", ".app_process64_" }; |
| 254 | + |
| 255 | + /** |
| 256 | + * Clean up leftover files from our cache directory.<br> |
| 257 | + * <br> |
| 258 | + * In ideal circumstances no files should be left dangling, but in practise it happens sooner |
| 259 | + * or later anyway. Periodically (once per app launch or per boot) calling this method is |
| 260 | + * advised.<br> |
| 261 | + * <br> |
| 262 | + * This method should be called from a background thread, as it performs disk i/o.<br> |
| 263 | + * <br> |
| 264 | + * It is difficult to determine which of these files may actually be in use, especially in |
| 265 | + * daemon mode. We try to determine device boot time, and wipe everything from before that |
| 266 | + * time. For safety we explicitly keep files using our current UUID. |
| 267 | + * |
| 268 | + * @param context Context to retrieve cache directory from |
| 269 | + */ |
| 270 | + public static void cleanupCache(Context context) { |
| 271 | + cleanupCache(context, CLEANUP_CACHE_PREFIXES); |
| 272 | + } |
| 273 | + |
| 274 | + /** |
| 275 | + * Clean up leftover files from our cache directory.<br> |
| 276 | + * <br> |
| 277 | + * This version is for internal use, see {@link #cleanupCache(Context)} instead. |
| 278 | + * |
| 279 | + * @param context Context to retrieve cache directory from |
| 280 | + * @param prefixes List of prefixes to scrub |
| 281 | + */ |
| 282 | + public static void cleanupCache(Context context, final String[] prefixes) { |
| 283 | + try { |
| 284 | + File cacheDir = context.getCacheDir(); |
| 285 | + if (cacheDir.exists()) { |
| 286 | + // determine time of last boot |
| 287 | + long boot = System.currentTimeMillis() - SystemClock.elapsedRealtime(); |
| 288 | + |
| 289 | + // find our files |
| 290 | + for (File file : cacheDir.listFiles(new FilenameFilter() { |
| 291 | + @Override |
| 292 | + public boolean accept(File dir, String name) { |
| 293 | + boolean accept = false; |
| 294 | + for (String prefix : prefixes) { |
| 295 | + // just in case: don't return files that contain our current uuid |
| 296 | + if (name.startsWith(prefix) && !name.endsWith(AppProcess.UUID)) { |
| 297 | + accept = true; |
| 298 | + break; |
| 299 | + } |
| 300 | + } |
| 301 | + return accept; |
| 302 | + } |
| 303 | + })) { |
| 304 | + if (file.lastModified() < boot) { |
| 305 | + //noinspection ResultOfMethodCallIgnored |
| 306 | + file.delete(); |
| 307 | + } |
| 308 | + } |
| 309 | + } |
| 310 | + } catch (Exception e) { |
| 311 | + Logger.ex(e); |
| 312 | + } |
| 313 | + } |
| 314 | + |
250 | 315 | // ------------------------ calls for root ------------------------ |
251 | 316 |
|
252 | 317 | /** |
|
0 commit comments