// // Copyright 2005 The Android Open Source Project // // Our collection of devices. // // For compilers that support precompilation, include "wx/wx.h". #include "wx/wxprec.h" // Otherwise, include all standard headers #ifndef WX_PRECOMP # include "wx/wx.h" #endif //#include "wx/image.h" // needed for Windows build #include "PhoneCollection.h" #include "PhoneData.h" #include "MyApp.h" #include "utils.h" #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <assert.h> using namespace android; /*static*/ PhoneCollection* PhoneCollection::mpInstance = NULL; /*static*/ const char* PhoneCollection::kLayoutFile = "layout.xml"; /* * (Re-)scan the specified directory for phones. We register a hit if we can * see a file called "<directory>/layout.xml". */ void PhoneCollection::ScanForPhones(const char* directory) { /* * Scan through the directory and find everything that looks like it * might hold phone data. */ StringArray strArr; #ifdef BEFORE_ASSET DIR* dirp; struct dirent* entp; dirp = opendir(directory); if (dirp == NULL) { char buf[512]; fprintf(stderr, "ERROR: unable to scan directory '%s' for phone data\n", directory); fprintf(stderr, "Current dir is %s\n", getcwd(buf, sizeof(buf))); return; } while (1) { wxString dirName; wxString fileName; entp = readdir(dirp); if (entp == NULL) break; // done with scan dirName = directory; dirName += '/'; dirName += entp->d_name; fileName = dirName; fileName += '/'; fileName += kLayoutFile; if (access(fileName, R_OK) == 0) { strArr.push_back(dirName); //printf("--- examining '%s'\n", (const char*) fileName); } } closedir(dirp); #else android::AssetManager* pAssetMgr = ((MyApp*)wxTheApp)->GetAssetManager(); android::AssetDir* pDir; int i, count; pDir = pAssetMgr->openDir(""); assert(pDir != NULL); count = pDir->getFileCount(); for (i = 0; i < count; i++) { android::String8 layoutPath; if (pDir->getFileType(i) != kFileTypeDirectory) continue; layoutPath = pDir->getFileName(i); layoutPath.appendPath(kLayoutFile); if (pAssetMgr->getFileType(layoutPath.string()) == kFileTypeRegular) { strArr.push_back(pDir->getFileName(i).string()); printf("--- examining '%s'\n", layoutPath.string()); } } delete pDir; #endif if (strArr.size() == 0) { fprintf(stderr, "ERROR: no phone data found in '%s'\n", directory); return; } /* * Found some candidates. If they parse successfully, add them to * our list. * * We sort them first, because it's nice when everybody's user * interface looks the same. Note we're sorting the directory name, * so it's possible to define a sort order in the filesystem that * doesn't require messing up the phone's title string. */ mPhoneList.clear(); strArr.sort(StringArray::cmpAscendingAlpha); for (int i = 0; i < strArr.size(); i++) { PhoneData tmpPhone; if (!tmpPhone.Create(strArr.getEntry(i))) { fprintf(stderr, "Sim: Abandoning phone '%s'\n", strArr.getEntry(i)); //strArr.erase(i); //i--; } else { if (GetPhoneData(tmpPhone.GetName()) != NULL) { fprintf(stderr, "Sim: ERROR: duplicate name '%s' in '%s'\n", tmpPhone.GetName(), strArr.getEntry(i)); } else { mPhoneList.push_back(tmpPhone); } } } } /* * Return the Nth member of the phone data array. (Replace w/Vector.) */ PhoneData* PhoneCollection::GetPhoneData(int idx) { typedef List<PhoneData>::iterator Iter; for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) { if (idx == 0) return &(*ii); --idx; } return NULL; } /* * Return the entry whose phone data name matches "name". */ PhoneData* PhoneCollection::GetPhoneData(const char* name) { typedef List<PhoneData>::iterator Iter; for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) { if (strcasecmp((*ii).GetName(), name) == 0) return &(*ii); } return NULL; }