source: trunk/autoquest-androidmonitor/src/main/java/de/ugoe/cs/autoquest/androidmonitor/AndroidMonitorLogFile.java @ 1833

Last change on this file since 1833 was 1833, checked in by funger, 10 years ago
  • Property svn:mime-type set to text/plain
File size: 18.0 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.androidmonitor;
16
17import java.io.File;
18import java.io.FileNotFoundException;
19import java.io.FileOutputStream;
20import java.io.IOException;
21import java.io.StringWriter;
22import java.util.ArrayList;
23import java.util.List;
24
25import org.xmlpull.v1.XmlSerializer;
26
27import android.util.Log;
28import android.util.Xml;
29import android.view.View;
30import android.view.ViewGroup;
31
32/**
33 * <p>
34 * TODO comment
35 * </p>
36 *
37 * @author Florian Unger
38 * @version 1.0
39 */
40public class AndroidMonitorLogFile {
41
42    /**
43     * <p>
44     * Name of the log file which is stored in the internal space of the device.
45     * </p>
46     */
47    private String name;
48   
49    /**
50     * <p>
51     * File representation to store monitored information.
52     * </p>
53     */
54    private File file;
55   
56    /**
57     * <p>
58     * List representing all components which was written to log file before.
59     * </p>
60     */
61    private List<Integer> currentLoggedComponents;
62
63    /**
64     *
65     * <p>
66     * Constructor. Creates a new AndroidmonitorLogFile.
67     * </p>
68     *
69     * @param appName
70     *          Name of the calling application.
71     * @param dir
72     *          Folder to store the log file.
73     */
74    public AndroidMonitorLogFile(String appName, File dir) {
75       
76        currentLoggedComponents = new ArrayList<Integer>();
77       
78        this.name = "androidLogFile_" + appName + System.currentTimeMillis() + ".log";
79
80        try {
81                // prove if file exists
82                this.file = new File(dir, this.name);
83                /*
84                 * if file does not exists write device and app information to a new
85                 * file. Otherwise use existing file and add activity information to
86                 * file.
87                 */
88                // TODO prove if file exists and add activity information
89                if (true) { // !this.file.exists()
90                        /*
91                         * create log file. Using method openFileOutput() does not work
92                         * for this project due to the reason that this method would try
93                         * to create the file in the directory of the non-existing
94                         * directory de.ugoe.cs.androidmonitor. This directory does not
95                         * exist due to the reason that this project is a library and
96                         * the file has to be stored in the directory of the running
97                         * application. Furthermore it would not be possible to write in
98                         * another app directory as the own one.
99                         */
100
101                        String string = "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><sessions>";
102                       
103                        try {
104                                FileOutputStream outputStream = new FileOutputStream(
105                                                this.file);
106                                outputStream.write(string.getBytes());
107                                outputStream.close();
108                        } catch (Exception e) {
109                                Log.e("this.file", "outputstream: " + e.getMessage());
110                        }
111                       
112                        setDeviceInformation();
113                        setAppInformation();
114
115                }
116                /*else {
117                        // TODO add activity information
118                }*/
119        } catch (Exception e) {
120                e.printStackTrace();
121                Log.e("file", "file: " + e.getMessage());
122        }
123    }
124
125    /**
126     *
127     * <p>
128     * Get file name which is in use.
129     * </p>
130     *
131     * @return filename
132     */
133    public String getFileName() {
134            return this.name;
135    }
136
137    /**
138     *
139     * <p>
140     * Writes information about the application to the log file.
141     * </p>
142     *
143     */
144    private void setAppInformation() {
145            // TODO create app information in the same manner as coded in
146            // getDeviceInformation
147           
148    }
149
150    /**
151     * <p>
152     * Query device information and store it to log file.
153     * </p>
154     *
155     */
156    private void setDeviceInformation() {
157           
158            XmlSerializer serializer = Xml.newSerializer();
159            StringWriter writer = new StringWriter();
160            try {
161                    serializer.setOutput(writer);
162                    serializer.startTag("", "device");
163                    serializer.startTag("", "param");
164                    serializer.attribute("", "value", ""
165                                    + android.os.Build.VERSION.SDK_INT);
166                    serializer.attribute("", "name", "sdk_version");
167                    serializer.endTag("", "param");
168
169                    serializer.startTag("", "param");
170                    serializer.attribute("", "value", android.os.Build.DEVICE);
171                    serializer.attribute("", "name", "device");
172                    serializer.endTag("", "param");
173
174                    serializer.startTag("", "param");
175                    serializer.attribute("", "value", android.os.Build.MANUFACTURER);
176                    serializer.attribute("", "name", "manufacturer");
177                    serializer.endTag("", "param");
178
179                    serializer.startTag("", "param");
180                    serializer.attribute("", "value", android.os.Build.MODEL);
181                    serializer.attribute("", "name", "model");
182                    serializer.endTag("", "param");
183
184                    // TODO get resolution ...
185
186                    serializer.endTag("", "device");
187                    serializer.endDocument();
188                   
189                    writeToFile(writer.toString());
190
191            } catch (IllegalArgumentException e) {
192                // TODO Auto-generated catch block
193                e.printStackTrace();
194                Log.e("file", "outputstream: " + e.getMessage());
195            } catch (IllegalStateException e) {
196                    // TODO Auto-generated catch block
197                    e.printStackTrace();
198                    Log.e("file", "outputstream: " + e.getMessage());
199            } catch (IOException e) {
200                    // TODO Auto-generated catch block
201                    e.printStackTrace();
202                    Log.e("file", "outputstream: " + e.getMessage());
203            }
204
205           
206    }
207
208    /**
209     * <p>
210     * Adds some information of an component of an activity (view) to the file.
211     * </p>
212     *
213     * @param view
214     *            view to be logged
215     * @param parentHash
216     *            hash of the parent view
217     * @param activityName
218     *            name of the activity that is analyzed
219     */
220    public void addComponent(View view, int parentHash, String activityName) {
221            XmlSerializer serializer = Xml.newSerializer();
222            StringWriter writer = new StringWriter();
223           
224            try {
225                    serializer.setOutput(writer);
226                    serializer.startTag("", "component");
227                    // TODO find a way in that the hash code is unique over time and
228                    // target
229                    /*
230                     * (non-Javadoc) view.getId() seems to be unique over time and
231                     * targets but there is a problem. In some cases there is no ID
232                     * (value: -1).
233                     */
234                    serializer.attribute("", "hash", "" + view.hashCode());
235                   
236
237                    serializer.startTag("", "param");
238                    serializer.attribute("", "name", "id");
239                    serializer.attribute("", "value", "" + view.getId());
240                    serializer.endTag("", "param");
241
242                    serializer.startTag("", "param");
243                    serializer.attribute("", "name", "path");
244                    serializer.attribute("", "value", activityName + "/"
245                                    + getViewPath(view) + view.getClass().getSimpleName());
246                    serializer.endTag("", "param");
247
248                    serializer.startTag("", "param");
249                    serializer.attribute("", "name", "class");
250                    serializer.attribute("", "value", view.getClass().getName());
251                    serializer.endTag("", "param");
252
253                    serializer.startTag("", "param");
254                    serializer.attribute("", "name", "parent");
255                    // Problem in using view.getParent().hashCode():
256                    // http://developer.android.com/reference/android/view/View.html#getParent()
257                    // tells: "... parent is a ViewParent and not necessarily a View."
258                    // ViewParent does not have a method hashCode(). Solution is done
259                    // add parentHash as parameter to method addComponent() and
260                    // Androidmonitor-> addLogListenerToView.
261                    serializer.attribute("", "value", "" + parentHash);
262                    serializer.endTag("", "param");
263
264                    // TODO add title e.g. android:text="Button"
265
266                    serializer.startTag("", "ancestors");
267                   
268                    Class<? extends Object> classobject = view.getClass();
269                   
270                    while((classobject != null)){
271                            serializer.startTag("", "ancestor");
272                            serializer.attribute("", "name", classobject.getName());
273                            serializer.endTag("", "ancestor");
274                            classobject = classobject.getSuperclass();
275                    }
276                    serializer.endTag("", "ancestors");
277
278                    serializer.endTag("", "component");
279                    serializer.endDocument();
280
281                    writeToFile(writer.toString());
282
283            } catch (IllegalArgumentException e) {
284                    // TODO Auto-generated catch block
285                    e.printStackTrace();
286                    Log.e("file", "outputstream: " + e.getMessage());
287            } catch (IllegalStateException e) {
288                    // TODO Auto-generated catch block
289                    e.printStackTrace();
290                    Log.e("file", "outputstream: " + e.getMessage());
291            } catch (IOException e) {
292                    // TODO Auto-generated catch block
293                    e.printStackTrace();
294                    Log.e("file", "outputstream: " + e.getMessage());
295            }
296
297    }
298
299    /**
300     * <p>
301     * Add an event to the log file
302     * </p>
303     *
304     * @param hash
305     *                      hash value of the calling view of the listener
306     * @param type
307     *                      the type of listener e.g. textView ...
308     * @param message
309     *                      message typed in
310     */
311    public void addEvent(int hash, String type, String message){
312            XmlSerializer serializer = Xml.newSerializer();
313            StringWriter writer = new StringWriter();
314
315            try {
316                    serializer.setOutput(writer);
317
318                    serializer.startTag("", "event");
319                    serializer.attribute("", "id", type);
320
321                    serializer.startTag("", "param");
322                    serializer.attribute("", "value", "" + hash);
323                    serializer.attribute("", "name", "source");
324                    serializer.endTag("", "param");
325                   
326                    serializer.startTag("", "param");
327                    serializer.attribute("", "value", message);
328                    serializer.attribute("", "name", "message");
329                    serializer.endTag("", "param");
330
331                    serializer.startTag("", "param");
332                    serializer.attribute("", "value", "" + System.currentTimeMillis());
333                    serializer.attribute("", "name", "timestamp");
334                    serializer.endTag("", "param");
335
336                    serializer.endTag("", "event");
337                    serializer.endDocument();
338
339                    writeToFile(writer.toString());
340            } catch (IllegalArgumentException e) {
341                    // TODO Auto-generated catch block
342                    e.printStackTrace();
343                    Log.e("file", "outputstream: " + e.getMessage());
344            } catch (IllegalStateException e) {
345                    // TODO Auto-generated catch block
346                    e.printStackTrace();
347                    Log.e("file", "outputstream: " + e.getMessage());
348            } catch (IOException e) {
349                    // TODO Auto-generated catch block
350                    e.printStackTrace();
351                    Log.e("file", "outputstream: " + e.getMessage());
352            }
353    }
354   
355    /**
356     * <p>
357     * Add an event to the log file
358     * </p>
359     *
360     * @param view
361     *            the calling view of the listener
362     * @param type
363     *            the type of listener e.g. onClick ...
364     */
365    public void addEvent(View view, String type) {
366
367            String x = "" + view.getX();
368            String y = "" + view.getY();
369
370            XmlSerializer serializer = Xml.newSerializer();
371            StringWriter writer = new StringWriter();
372
373            try {
374                    serializer.setOutput(writer);
375
376                    serializer.startTag("", "event");
377                    serializer.attribute("", "id", type);
378
379                    serializer.startTag("", "param");
380                    serializer.attribute("", "value", x);
381                    serializer.attribute("", "name", "X");
382                    serializer.endTag("", "param");
383
384                    serializer.startTag("", "param");
385                    serializer.attribute("", "value", y);
386                    serializer.attribute("", "name", "Y");
387                    serializer.endTag("", "param");
388
389                    serializer.startTag("", "param");
390                    serializer.attribute("", "value", "" + view.hashCode());
391                    serializer.attribute("", "name", "source");
392                    serializer.endTag("", "param");
393
394                    serializer.startTag("", "param");
395                    serializer.attribute("", "value", "" + System.currentTimeMillis());
396                    serializer.attribute("", "name", "timestamp");
397                    serializer.endTag("", "param");
398
399                    serializer.endTag("", "event");
400                    serializer.endDocument();
401
402                    writeToFile(writer.toString());
403            } catch (IllegalArgumentException e) {
404                    // TODO Auto-generated catch block
405                    e.printStackTrace();
406                    Log.e("file", "outputstream: " + e.getMessage());
407            } catch (IllegalStateException e) {
408                    // TODO Auto-generated catch block
409                    e.printStackTrace();
410                    Log.e("file", "outputstream: " + e.getMessage());
411            } catch (IOException e) {
412                    // TODO Auto-generated catch block
413                    e.printStackTrace();
414                    Log.e("file", "outputstream: " + e.getMessage());
415            }
416    }
417
418    /**
419     * <p>
420     * Writes given information to the file. e.g. previous produced XML
421     * statements.
422     * </p>
423     *
424     * @param data
425     *            content to add to the file
426     */
427    private void writeToFile(String data) {
428
429            FileOutputStream outputStream;
430            try {
431                    outputStream = new FileOutputStream(file, true);
432                    outputStream.write(data.getBytes());
433                    outputStream.close();
434            } catch (FileNotFoundException e) {
435                    e.printStackTrace();
436                    Log.e("file", "outputstream: " + e.getMessage());
437            } catch (IOException e) {
438                    e.printStackTrace();
439                    Log.e("file", "outputstream: " + e.getMessage());
440            }
441
442    }
443
444    /**
445     * <p>
446     * Generates the path of an view element.
447     * </p>
448     *
449     * @param view
450     * @return path path to the element
451     */
452    private String getViewPath(View view) {
453            return getViewPath(view, null);
454    }
455
456    /**
457     * <p>
458     * Generates the path of an view element.
459     * </p>
460     *
461     * @param view
462     * @param path
463     * @return path path to the element
464     */
465    private String getViewPath(View view, String path) {
466            if (path == null) {
467                    path = "";
468            } else {
469                    path = view.getClass().getSimpleName() + "/" + path;
470            }
471            if (view.getParent() != null && (view.getParent() instanceof ViewGroup)) {
472                    return getViewPath((View) view.getParent(), path);
473            } else {
474                    return path;
475            }
476    }
477   
478    /**
479     *
480     * <p>
481     * Check whether a component is still written to log file.
482     * </p>
483     *
484     * @param hashCode
485     *          hash code of the view
486     * @return
487     */
488    public Boolean isComponentLogged(Integer hashCode){
489        return currentLoggedComponents.contains(hashCode);
490    }
491   
492   
493}
Note: See TracBrowser for help on using the repository browser.