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