1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.packageinstaller; 18 19 import android.annotation.NonNull; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.os.SystemClock; 24 import android.util.Log; 25 26 import java.io.File; 27 import java.io.IOException; 28 29 /** 30 * Manages files of the package installer and resets state during boot. 31 */ 32 public class TemporaryFileManager extends BroadcastReceiver { 33 private static final String LOG_TAG = TemporaryFileManager.class.getSimpleName(); 34 35 /** 36 * Create a new file to hold a staged file. 37 * 38 * @param context The context of the caller 39 * 40 * @return A new file 41 */ 42 @NonNull getStagedFile(@onNull Context context)43 public static File getStagedFile(@NonNull Context context) throws IOException { 44 return File.createTempFile("package", ".apk", context.getNoBackupFilesDir()); 45 } 46 47 /** 48 * Get the file used to store the results of installs. 49 * 50 * @param context The context of the caller 51 * 52 * @return the file used to store the results of installs 53 */ 54 @NonNull getInstallStateFile(@onNull Context context)55 public static File getInstallStateFile(@NonNull Context context) { 56 return new File(context.getNoBackupFilesDir(), "install_results.xml"); 57 } 58 59 /** 60 * Get the file used to store the results of uninstalls. 61 * 62 * @param context The context of the caller 63 * 64 * @return the file used to store the results of uninstalls 65 */ 66 @NonNull getUninstallStateFile(@onNull Context context)67 public static File getUninstallStateFile(@NonNull Context context) { 68 return new File(context.getNoBackupFilesDir(), "uninstall_results.xml"); 69 } 70 71 @Override onReceive(Context context, Intent intent)72 public void onReceive(Context context, Intent intent) { 73 long systemBootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime(); 74 75 File[] filesOnBoot = context.getNoBackupFilesDir().listFiles(); 76 77 if (filesOnBoot == null) { 78 return; 79 } 80 81 for (int i = 0; i < filesOnBoot.length; i++) { 82 File fileOnBoot = filesOnBoot[i]; 83 84 if (systemBootTime > fileOnBoot.lastModified()) { 85 boolean wasDeleted = fileOnBoot.delete(); 86 if (!wasDeleted) { 87 Log.w(LOG_TAG, "Could not delete " + fileOnBoot.getName() + " onBoot"); 88 } 89 } else { 90 Log.w(LOG_TAG, fileOnBoot.getName() + " was created before onBoot broadcast was " 91 + "received"); 92 } 93 } 94 } 95 } 96