Home | History | Annotate | Download | only in app
      1 //
      2 // Copyright 2005 The Android Open Source Project
      3 //
      4 // Our collection of devices.
      5 //
      6 
      7 // For compilers that support precompilation, include "wx/wx.h".
      8 #include "wx/wxprec.h"
      9 
     10 // Otherwise, include all standard headers
     11 #ifndef WX_PRECOMP
     12 # include "wx/wx.h"
     13 #endif
     14 //#include "wx/image.h"   // needed for Windows build
     15 
     16 
     17 #include "PhoneCollection.h"
     18 #include "PhoneData.h"
     19 #include "MyApp.h"
     20 
     21 #include "utils.h"
     22 
     23 #include <stdlib.h>
     24 #include <unistd.h>
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <sys/types.h>
     28 #include <dirent.h>
     29 #include <assert.h>
     30 
     31 using namespace android;
     32 
     33 /*static*/ PhoneCollection* PhoneCollection::mpInstance = NULL;
     34 
     35 /*static*/ const char* PhoneCollection::kLayoutFile = "layout.xml";
     36 
     37 
     38 /*
     39  * (Re-)scan the specified directory for phones.  We register a hit if we can
     40  * see a file called "<directory>/layout.xml".
     41  */
     42 void PhoneCollection::ScanForPhones(const char* directory)
     43 {
     44     /*
     45      * Scan through the directory and find everything that looks like it
     46      * might hold phone data.
     47      */
     48     StringArray strArr;
     49 
     50 #ifdef BEFORE_ASSET
     51     DIR* dirp;
     52     struct dirent* entp;
     53 
     54     dirp = opendir(directory);
     55     if (dirp == NULL) {
     56         char buf[512];
     57         fprintf(stderr, "ERROR: unable to scan directory '%s' for phone data\n",
     58             directory);
     59         fprintf(stderr, "Current dir is %s\n", getcwd(buf, sizeof(buf)));
     60         return;
     61     }
     62 
     63     while (1) {
     64         wxString dirName;
     65         wxString fileName;
     66 
     67         entp = readdir(dirp);
     68         if (entp == NULL)
     69             break;              // done with scan
     70         dirName = directory;
     71         dirName += '/';
     72         dirName += entp->d_name;
     73         fileName = dirName;
     74         fileName += '/';
     75         fileName += kLayoutFile;
     76 
     77         if (access(fileName, R_OK) == 0) {
     78             strArr.push_back(dirName);
     79             //printf("--- examining '%s'\n", (const char*) fileName);
     80         }
     81     }
     82     closedir(dirp);
     83 #else
     84     android::AssetManager* pAssetMgr = ((MyApp*)wxTheApp)->GetAssetManager();
     85     android::AssetDir* pDir;
     86     int i, count;
     87 
     88     pDir = pAssetMgr->openDir("");
     89     assert(pDir != NULL);
     90     count = pDir->getFileCount();
     91 
     92     for (i = 0; i < count; i++) {
     93         android::String8 layoutPath;
     94 
     95         if (pDir->getFileType(i) != kFileTypeDirectory)
     96             continue;
     97 
     98         layoutPath = pDir->getFileName(i);
     99         layoutPath.appendPath(kLayoutFile);
    100 
    101         if (pAssetMgr->getFileType(layoutPath.string()) == kFileTypeRegular) {
    102             strArr.push_back(pDir->getFileName(i).string());
    103             printf("--- examining '%s'\n", layoutPath.string());
    104         }
    105     }
    106 
    107     delete pDir;
    108 #endif
    109 
    110     if (strArr.size() == 0) {
    111         fprintf(stderr, "ERROR: no phone data found in '%s'\n", directory);
    112         return;
    113     }
    114 
    115     /*
    116      * Found some candidates.  If they parse successfully, add them to
    117      * our list.
    118      *
    119      * We sort them first, because it's nice when everybody's user
    120      * interface looks the same.  Note we're sorting the directory name,
    121      * so it's possible to define a sort order in the filesystem that
    122      * doesn't require messing up the phone's title string.
    123      */
    124     mPhoneList.clear();
    125     strArr.sort(StringArray::cmpAscendingAlpha);
    126 
    127     for (int i = 0; i < strArr.size(); i++) {
    128         PhoneData tmpPhone;
    129 
    130         if (!tmpPhone.Create(strArr.getEntry(i))) {
    131             fprintf(stderr, "Sim: Abandoning phone '%s'\n", strArr.getEntry(i));
    132             //strArr.erase(i);
    133             //i--;
    134         } else {
    135             if (GetPhoneData(tmpPhone.GetName()) != NULL) {
    136                 fprintf(stderr, "Sim: ERROR: duplicate name '%s' in '%s'\n",
    137                     tmpPhone.GetName(), strArr.getEntry(i));
    138             } else {
    139                 mPhoneList.push_back(tmpPhone);
    140             }
    141         }
    142     }
    143 }
    144 
    145 
    146 /*
    147  * Return the Nth member of the phone data array.  (Replace w/Vector.)
    148  */
    149 PhoneData* PhoneCollection::GetPhoneData(int idx)
    150 {
    151     typedef List<PhoneData>::iterator Iter;
    152 
    153     for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) {
    154         if (idx == 0)
    155             return &(*ii);
    156         --idx;
    157     }
    158     return NULL;
    159 }
    160 
    161 /*
    162  * Return the entry whose phone data name matches "name".
    163  */
    164 PhoneData* PhoneCollection::GetPhoneData(const char* name)
    165 {
    166     typedef List<PhoneData>::iterator Iter;
    167 
    168     for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) {
    169         if (strcasecmp((*ii).GetName(), name) == 0)
    170             return &(*ii);
    171     }
    172     return NULL;
    173 }
    174 
    175