Home | History | Annotate | only in /development/tools/apkcheck
Up to higher level directory
NameDateSize
Android.mk13-Nov-20121.4K
etc/13-Nov-2012
README.txt13-Nov-20126.8K
src/13-Nov-2012

README.txt

      1 Android APK Checker
      2 
      3 This compares the set of classes, fields, and methods used by an Android
      4 application against the published API.  It identifies and reports the
      5 use of any unpublished members or methods.
      6 
      7 The public API description files live in the source tree, in
      8 frameworks/base/api/.  The tip-of-tree version is in "current.xml",
      9 and each officially released API has a numbered file (e.g. "6.xml").
     10 They're generated from the sources, and can take into acount javadoc
     11 annotations like "@hide" in comments.
     12 
     13 The dependency set for an APK can be generated with "dexdeps".  It finds
     14 all classes, fields, and methods that are referenced by classes.dex but not
     15 defined locally.  The tool can't easily tell anything about a dependency
     16 beyond the name (e.g. whether a class is a static or non-static inner
     17 class), so while the output from dexdeps is similar in structure to the
     18 API XML file, it has much less detail.
     19 
     20 
     21 ==== Usage ====
     22 
     23 % apkcheck [options] public-api.xml apk1.xml ...
     24 
     25 Provide the public API data file of choice, and one or more XML files
     26 generated by dexdeps.  The time required to parse and manipulate the
     27 public API XML file is generally much larger than the time required to
     28 analyze the APK, so if you have a large set of APKs it's best to run them
     29 through in large batches.
     30 
     31 Options:
     32 
     33   --help
     34     Show options summary.
     35 
     36   --uses-library=<lib.xml>
     37     Load additional public API list.  This is intended for APKs that
     38     use "uses-library" directives to pull in external libraries.  Since
     39     the external libraries are not part of the public API, their use
     40     would otherwise be flagged as illegal by apkcheck.
     41 
     42   --ignore-package=<package-name>
     43     Ignore errors generated by references to the named package (e.g.
     44     "com.google.android.maps").  Warnings will be generated instead.
     45     Useful for ignoring references to shared library content when
     46     XML API data is not available.
     47 
     48   --[no-]warn
     49     Enable or disable warning messages.  These are disabled by default.
     50 
     51   --[no-]error
     52     Enable or disable error messages.  These are enabled by default.  If
     53     you disable both warnings and errors you will only see a summary.
     54 
     55 In some cases involving generic signatures it may not be possible
     56 to accurately reconstruct the public API.  Some popular cases have
     57 been hard-coded into the program.  They can be included by specifying
     58 "--uses-library=BUILTIN".
     59 
     60 Example use:
     61 
     62 % dexdeps out/target/product/sapphire/system/app/Gmail.apk > Gmail.apk.xml
     63 % apkcheck --uses-library=BUILTIN frameworks/base/api/current.xml Gmail.apk.xml
     64 Gmail.apk.xml: summary: 0 errors, 15 warnings
     65 
     66 
     67 ==== Limitations ====
     68 
     69 The API XML files have some ambiguous entries and are missing important
     70 pieces.  A summary of the issues follows.
     71 
     72 (1) Class names are not in binary form
     73 
     74 Example:
     75 
     76  type="android.os.Parcelable.Creator"
     77 
     78 This could be a Creator class in the package android.os.Parcelable,
     79 or Parcelable.Creator in the package android.os.  We can guess based on
     80 capitalization, but that's unreliable.
     81 
     82 The API XML does specify each package in a <package> tag, so we should have
     83 the full set of packages available.  From this we can remove one element
     84 at a time from the right until we match a known package.  This will work
     85 unless "android.os" and "android.os.Parcelable" are both valid packages.
     86 
     87 
     88 (2) Public enums are not enumerated
     89 
     90 Enumeration classes are included, and always have two methods ("valueOf"
     91 and "values").  What isn't included are entries for the fields representing
     92 the enumeration values.  This makes it look like an APK is referring
     93 to non-public fields in the class.
     94 
     95 If apkcheck sees a reference to an unknown field, and the field's defining
     96 class appears to be an Enum (the superclass is java.lang.Enum), we emit
     97 a warning instead of an error.
     98 
     99 
    100 (3) Public annotation methods are not listed
    101 
    102 Annotation classes have trivial entries that show only the class name
    103 and "implements java.lang.annotation.Annotation".  It is not possible
    104 to verify that a method call on an annotation is valid.
    105 
    106 If apkcheck sees a method call to an unknown method, and the class appears
    107 to be an annotation (extends Object, implements Annotation, defines no
    108 fields or methods), we emit a warning instead of an error.
    109 
    110 
    111 (4) Covariant return types
    112 
    113 Suppose a class defines a method "public Foo gimmeFoo()".  Any subclass
    114 that overrides that method must also return Foo, so it would seem that
    115 there's no need to emit a method entry for gimmeFoo() in the subclasses.
    116 
    117 However, it's possible to override gimmeFoo with "public MegaFoo
    118 gimmeFoo()" so long as MegaFoo is an instance of Foo.  In that case it
    119 is necessary to emit a new method entry, but the public API XML generator
    120 does not.
    121 
    122 If apkcheck can't find an exact match for a method reference, but can
    123 find a method that matches on everything but the return type, it will
    124 emit a warning instead of an error.  (We could be more thorough and try
    125 to verify that the return types are related, but that's more trouble than
    126 it's worth.)
    127 
    128 
    129 (5) Generic signatures
    130 
    131 When generic signatures are used, the public API file will contain
    132 entries like these:
    133 
    134  <parameter name="key" type="K">
    135  <parameter name="others" type="E...">
    136  <parameter name="map" type="java.util.Map&lt;? extends K, ? extends V&gt;">
    137 
    138 The generic types are generally indistinguishable from classes in the
    139 default package (i.e. that have no package name).  In most cases they're
    140 a single letter, so apkcheck includes a kluge that converts single-letter
    141 class names to java.lang.Object.
    142 
    143 This often works, but falls apart in a few cases.  For example:
    144 
    145  public <T extends Parcelable> T getParcelableExtra(String name) {
    146      return mExtras == null ? null : mExtras.<T>getParcelable(name);
    147  }
    148 
    149 This is emitted as:
    150 
    151  <method name="getParcelableExtra" return="T">
    152 
    153 which gets converted to java.lang.Object.  Unfortunately the APK wants
    154 a method with a more specific return type (android.os.Parcelable), so
    155 the lookup fails.
    156 
    157 There is no way to recover the actual type, because the generic signature
    158 details are not present in the XML.  This particular case will be handled
    159 as a covariant return type.  When the generic type is in the parameter
    160 list, though, this isn't handled so easily.
    161 
    162 These cases are relatively few, so they were handled by baking the
    163 signatures into the code (--uses-library=BUILTIN).  (At some point it
    164 may be worthwhile to try a little harder here.)
    165 
    166 
    167 (6) Use of opaque non-public types
    168 
    169 Some classes are not meant for public consumption, but are still referred
    170 to by application code.  For example, an opaque type might be passed to
    171 the app as a cookie.
    172 
    173 Another example is the Dalvik annotation classes, like
    174 dalvik.annotation.InnerClass.  These are emitted by "dx", and referenced
    175 from the DEX file, but not intended to be used by application code.
    176 
    177 If an APK refers to a non-public class, but doesn't access any fields
    178 or methods, a warning is emitted instead of an error.
    179 
    180