1 /* 2 * Copyright (C) 2009 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.certinstaller; 18 19 import android.os.Bundle; 20 import android.os.Environment; 21 import android.os.FileObserver; 22 import android.preference.Preference; 23 import android.preference.PreferenceScreen; 24 import android.util.Log; 25 import android.widget.Toast; 26 27 import java.io.File; 28 import java.io.IOException; 29 import java.util.List; 30 31 /** 32 * Lists certificate files in the SD card. User may click one to install it 33 * to the system keystore. 34 */ 35 public class CertFileList extends CertFile 36 implements Preference.OnPreferenceClickListener { 37 private static final String TAG = "CertFileList"; 38 39 private static final String DOWNLOAD_DIR = "download"; 40 41 private SdCardMonitor mSdCardMonitor; 42 43 @Override 44 protected void onCreate(Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 47 addPreferencesFromResource(R.xml.pick_file_pref); 48 createFileList(); 49 startSdCardMonitor(); 50 } 51 52 @Override 53 protected void onDestroy() { 54 super.onDestroy(); 55 stopSdCardMonitor(); 56 } 57 58 @Override 59 protected void onInstallationDone(boolean fileDeleted) { 60 super.onInstallationDone(fileDeleted); 61 if (!fileDeleted) { 62 if (isSdCardPresent()) { 63 setAllFilesEnabled(true); 64 } else { 65 Toast.makeText(this, R.string.sdcard_not_present, 66 Toast.LENGTH_SHORT).show(); 67 finish(); 68 } 69 } 70 } 71 72 @Override 73 protected void onError(int errorId) { 74 if (errorId == CERT_FILE_MISSING_ERROR) { 75 createFileList(); 76 } 77 } 78 79 private void setAllFilesEnabled(boolean enabled) { 80 PreferenceScreen root = getPreferenceScreen(); 81 for (int i = 0, n = root.getPreferenceCount(); i < n; i++) { 82 root.getPreference(i).setEnabled(enabled); 83 } 84 } 85 86 public boolean onPreferenceClick(Preference pref) { 87 File file = new File(Environment.getExternalStorageDirectory(), 88 pref.getTitle().toString()); 89 if (file.isDirectory()) { 90 Log.w(TAG, "impossible to pick a directory! " + file); 91 } else { 92 setAllFilesEnabled(false); 93 installFromFile(file); 94 } 95 return true; 96 } 97 98 private void createFileList() { 99 if (isFinishing()) { 100 Log.d(TAG, "finishing, exit createFileList()"); 101 return; 102 } 103 if (!isSdCardPresent()) { 104 Toast.makeText(this, R.string.sdcard_not_present, 105 Toast.LENGTH_SHORT).show(); 106 finish(); 107 return; 108 } 109 110 try { 111 PreferenceScreen root = getPreferenceScreen(); 112 root.removeAll(); 113 114 List<File> allFiles = getAllCertFiles(); 115 if (allFiles.isEmpty()) { 116 Toast.makeText(this, R.string.no_cert_file_found, 117 Toast.LENGTH_SHORT).show(); 118 finish(); 119 return; 120 } else { 121 int prefixEnd = Environment.getExternalStorageDirectory() 122 .getCanonicalPath().length() + 1; 123 for (File file : allFiles) { 124 Preference pref = new Preference(this); 125 pref.setTitle(file.getCanonicalPath().substring(prefixEnd)); 126 root.addPreference(pref); 127 pref.setOnPreferenceClickListener(this); 128 } 129 } 130 } catch (IOException e) { 131 // should not occur 132 Log.w(TAG, "createFileList(): " + e); 133 throw new RuntimeException(e); 134 } 135 } 136 137 private void startSdCardMonitor() { 138 if (mSdCardMonitor == null) { 139 mSdCardMonitor = new SdCardMonitor(); 140 } 141 mSdCardMonitor.startWatching(); 142 } 143 144 private void stopSdCardMonitor() { 145 if (mSdCardMonitor != null) { 146 mSdCardMonitor.stopWatching(); 147 } 148 } 149 150 private class SdCardMonitor { 151 FileObserver mRootMonitor; 152 FileObserver mDownloadMonitor; 153 154 SdCardMonitor() { 155 File root = Environment.getExternalStorageDirectory(); 156 mRootMonitor = new FileObserver(root.getPath()) { 157 @Override 158 public void onEvent(int evt, String path) { 159 commonHandler(evt, path); 160 } 161 }; 162 163 File download = new File(root, DOWNLOAD_DIR); 164 mDownloadMonitor = new FileObserver(download.getPath()) { 165 @Override 166 public void onEvent(int evt, String path) { 167 commonHandler(evt, path); 168 } 169 }; 170 } 171 172 private void commonHandler(int evt, String path) { 173 switch (evt) { 174 case FileObserver.CREATE: 175 case FileObserver.DELETE: 176 if (isFileAcceptable(path)) { 177 runOnUiThread(new Runnable() { 178 public void run() { 179 createFileList(); 180 } 181 }); 182 } 183 break; 184 } 185 }; 186 187 void startWatching() { 188 mRootMonitor.startWatching(); 189 mDownloadMonitor.startWatching(); 190 } 191 192 void stopWatching() { 193 mRootMonitor.stopWatching(); 194 mDownloadMonitor.stopWatching(); 195 } 196 } 197 } 198