The Android Open Source Project | 54b6cfa | 2008-10-21 07:00:00 -0700 | [diff] [blame] | 1 | # Copyright (C) 2008 The Android Open Source Project |
| 2 | |
| 3 | |
| 4 | - Description - |
| 5 | --------------- |
| 6 | |
| 7 | makeLayoutLib generates a library used by the Eclipse graphical layout editor |
| 8 | to perform layout. |
| 9 | |
| 10 | |
| 11 | |
| 12 | - Usage - |
| 13 | --------- |
| 14 | |
| 15 | ./makeLayoutLib path/to/android.jar destination.jar |
| 16 | |
| 17 | |
| 18 | |
| 19 | - Implementation Notes - |
| 20 | ------------------------ |
| 21 | |
| 22 | The goal of makeLayoutLib is to list all the classes from the input jar and create a new |
| 23 | jar that only keeps certain classes and create stubs for all their dependencies. |
| 24 | |
| 25 | First the input jar is parsed to find all the classes defined. |
| 26 | |
| 27 | In the Main(), the following list of classes are hardcoded (TODO config file later): |
| 28 | - keep all classes that derive from android.view.View. |
| 29 | - keep all classes in the android.view and android.widget packages (sub-packages excluded). |
| 30 | - keep specific classes such as android.policy.PhoneLayoutInflater. |
| 31 | |
| 32 | For each class to keep, their dependencies are examined using BCEL. |
| 33 | A dependency is defined as a class needed to instantiate the given class that should be kept, |
| 34 | directly or indirectly. So a dependency is a class that is used by the input class, that is |
| 35 | defined in the input jar and that is not part of the current JRE. |
| 36 | |
| 37 | Dependencies are computed recursively. |
| 38 | |
| 39 | Once all dependencies are found, the final jar can be created. |
| 40 | There are three kind of classes to write: |
| 41 | - classes that are to be kept as-is. They are just dumped in the new jar unchanged. |
| 42 | - classes that are to be kept yet contain native methods or fields. |
| 43 | - classes that are just dependencies. We don't want to expose their implementation in the final |
| 44 | jar. |
| 45 | |
| 46 | The implementation of native methods and all methods of mock classes is replaced by a stub |
| 47 | that throws UnsupportedOperationException. |
| 48 | |
| 49 | Incidentally, the access level of native and mock classes needs to be changed in order for |
| 50 | native methods to be later overridden. Methods that are "final private native" must become |
| 51 | non-final, non-native and at most protected. Package-default access is changed to public. |
| 52 | Classes that are final are made non-final. Abstract methods are left untouched. |
| 53 | |
| 54 | |
| 55 | |
| 56 | ---- |
| 57 | 20080617 Replace Class |
| 58 | |
| 59 | Some classes are basically wrappers over native objects. |
| 60 | Subclassing doesn't work as most methods are either static or we don't |
| 61 | control object creation. In this scenario the idea is to be able to |
| 62 | replace classes in the final jar. |
| 63 | |
| 64 | Example: android.graphics.Paint would get renamed to OriginalPaint |
| 65 | in the generated jar. Then in the bridge we'll introduce a replacement |
| 66 | Paint class that derives from OriginalPaint. |
| 67 | |
| 68 | This won't rename/replace the inner static methods of a given class. |
| 69 | |
| 70 | |
| 71 | |