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 
     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