blob: e1882cc59328922ae6be2a593e5fe7a06aa8ef70 [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001//
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
Mathias Agopian7380ec32009-05-31 19:12:43 -070021#include "utils.h"
The Android Open Source Project52d4c302009-03-03 19:29:09 -080022
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
31using 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 */
42void 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 */
149PhoneData* 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 */
164PhoneData* 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