Home | History | Annotate | Download | only in certinstaller
      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     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