1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.file;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstArray;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstLiteralBits;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Zeroes;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArrayAnnotatedOutput;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Writers;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Writer;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Arrays;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Representation of all the parts of a Dalvik class that are generally
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "inflated" into an in-memory representation at runtime. Instances of
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this class are represented in a compact streamable form in a
4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code dex} file, as opposed to a random-access form.
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class ClassDataItem extends OffsettedItem {
4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} what class this data is for, just for listing generation */
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final CstType thisClass;
46de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} list of static fields */
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<EncodedField> staticFields;
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} list of initial values for static fields */
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final HashMap<EncodedField, Constant> staticValues;
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} list of instance fields */
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<EncodedField> instanceFields;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} list of direct methods */
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<EncodedMethod> directMethods;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} list of virtual methods */
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<EncodedMethod> virtualMethods;
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} static initializer list; set in {@link #addContents} */
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CstArray staticValuesConstant;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} encoded form, ready for writing to a file; set during
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link #place0}
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private byte[] encodedForm;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance. Its sets of members are initially
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * empty.
74de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param thisClass {@code non-null;} what class this data is for, just
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for listing generation
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ClassDataItem(CstType thisClass) {
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(1, -1);
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thisClass == null) {
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("thisClass == null");
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.thisClass = thisClass;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.staticFields = new ArrayList<EncodedField>(20);
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.staticValues = new HashMap<EncodedField, Constant>(40);
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.instanceFields = new ArrayList<EncodedField>(20);
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.directMethods = new ArrayList<EncodedMethod>(20);
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.virtualMethods = new ArrayList<EncodedMethod>(20);
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.staticValuesConstant = null;
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ItemType itemType() {
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ItemType.TYPE_CLASS_DATA_ITEM;
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toHuman() {
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return toString();
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns whether this instance is empty.
108de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code true} if this instance is empty or
11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false} if at least one element has been added to it
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isEmpty() {
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return staticFields.isEmpty() && instanceFields.isEmpty()
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            && directMethods.isEmpty() && virtualMethods.isEmpty();
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a static field.
119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param field {@code non-null;} the field to add
12199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param value {@code null-ok;} initial value for the field, if any
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addStaticField(EncodedField field, Constant value) {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (field == null) {
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("field == null");
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (staticValuesConstant != null) {
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException(
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "static fields already sorted");
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        staticFields.add(field);
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        staticValues.put(field, value);
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an instance field.
139de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param field {@code non-null;} the field to add
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addInstanceField(EncodedField field) {
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (field == null) {
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("field == null");
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        instanceFields.add(field);
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
15199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Adds a direct ({@code static} and/or {@code private}) method.
152de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} the method to add
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addDirectMethod(EncodedMethod method) {
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (method == null) {
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("method == null");
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        directMethods.add(method);
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a virtual method.
165de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} the method to add
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addVirtualMethod(EncodedMethod method) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (method == null) {
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("method == null");
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        virtualMethods.add(method);
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets all the methods in this class. The returned list is not linked
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * in any way to the underlying lists contained in this instance, but
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the objects contained in the list are shared.
180de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} list of all methods
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ArrayList<EncodedMethod> getMethods() {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = directMethods.size() + virtualMethods.size();
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ArrayList<EncodedMethod> result = new ArrayList<EncodedMethod>(sz);
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.addAll(directMethods);
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.addAll(virtualMethods);
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Prints out the contents of this instance, in a debugging-friendly
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * way.
197de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
19899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to output to
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param verbose whether to be verbose with the output
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void debugPrint(Writer out, boolean verbose) {
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        PrintWriter pw = Writers.printWriterFor(out);
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = staticFields.size();
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pw.println("  sfields[" + i + "]: " + staticFields.get(i));
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sz = instanceFields.size();
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pw.println("  ifields[" + i + "]: " + instanceFields.get(i));
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sz = directMethods.size();
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pw.println("  dmeths[" + i + "]:");
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            directMethods.get(i).debugPrint(pw, verbose);
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sz = virtualMethods.size();
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pw.println("  vmeths[" + i + "]:");
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            virtualMethods.get(i).debugPrint(pw, verbose);
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addContents(DexFile file) {
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!staticFields.isEmpty()) {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            getStaticValuesConstant(); // Force the fields to be sorted.
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (EncodedField field : staticFields) {
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                field.addContents(file);
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!instanceFields.isEmpty()) {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Collections.sort(instanceFields);
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (EncodedField field : instanceFields) {
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                field.addContents(file);
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!directMethods.isEmpty()) {
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Collections.sort(directMethods);
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (EncodedMethod method : directMethods) {
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                method.addContents(file);
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!virtualMethods.isEmpty()) {
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Collections.sort(virtualMethods);
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (EncodedMethod method : virtualMethods) {
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                method.addContents(file);
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a {@link CstArray} corresponding to {@link #staticValues} if
26199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * it contains any non-zero non-{@code null} values.
262de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
26399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the corresponding constant or {@code null} if
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * there are no values to encode
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public CstArray getStaticValuesConstant() {
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((staticValuesConstant == null) && (staticFields.size() != 0)) {
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            staticValuesConstant = makeStaticValuesConstant();
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return staticValuesConstant;
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a {@link CstArray} corresponding to {@link #staticValues} if
27699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * it contains any non-zero non-{@code null} values.
277de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
27899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the corresponding constant or {@code null} if
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * there are no values to encode
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CstArray makeStaticValuesConstant() {
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // First sort the statics into their final order.
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Collections.sort(staticFields);
284de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Get the size of staticValues minus any trailing zeros/nulls (both
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * nulls per se as well as instances of CstKnownNull).
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int size = staticFields.size();
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (size > 0) {
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            EncodedField field = staticFields.get(size - 1);
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Constant cst = staticValues.get(field);
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cst instanceof CstLiteralBits) {
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Note: CstKnownNull extends CstLiteralBits.
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (((CstLiteralBits) cst).getLongBits() != 0) {
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if (cst != null) {
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            size--;
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (size == 0) {
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
308de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // There is something worth encoding, so build up a result.
310de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CstArray.List list = new CstArray.List(size);
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < size; i++) {
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            EncodedField field = staticFields.get(i);
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Constant cst = staticValues.get(field);
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cst == null) {
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                cst = Zeroes.zeroFor(field.getRef().getType());
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            list.set(i, cst);
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        list.setImmutable();
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new CstArray(list);
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void place0(Section addedTo, int offset) {
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Encode the data and note the size.
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeOutput(addedTo.getFile(), out);
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodedForm = out.toByteArray();
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        setWriteSize(encodedForm.length);
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Writes out the encoded form of this instance.
339de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
34099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param file {@code non-null;} file this instance is part of
34199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to write to
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void encodeOutput(DexFile file, AnnotatedOutput out) {
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean annotates = out.annotates();
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotates) {
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(0, offsetString() + " class data for " +
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    thisClass.toHuman());
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeSize(file, out, "static_fields", staticFields.size());
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeSize(file, out, "instance_fields", instanceFields.size());
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeSize(file, out, "direct_methods", directMethods.size());
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeSize(file, out, "virtual_methods", virtualMethods.size());
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeList(file, out, "static_fields", staticFields);
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeList(file, out, "instance_fields", instanceFields);
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeList(file, out, "direct_methods", directMethods);
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        encodeList(file, out, "virtual_methods", virtualMethods);
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotates) {
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.endAnnotation();
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
365de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper for {@link #encodeOutput}, which writes out the given
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * size value, annotating it as well (if annotations are enabled).
369de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
37099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param file {@code non-null;} file this instance is part of
37199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to write to
37299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code non-null;} the label for the purposes of annotation
37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param size {@code >= 0;} the size to write
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static void encodeSize(DexFile file, AnnotatedOutput out,
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String label, int size) {
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (out.annotates()) {
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(String.format("  %-21s %08x", label + "_size:",
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            size));
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.writeUnsignedLeb128(size);
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper for {@link #encodeOutput}, which writes out the given
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list. It also annotates the items (if any and if annotations
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * are enabled).
389de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
39099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param file {@code non-null;} file this instance is part of
39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to write to
39299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param label {@code non-null;} the label for the purposes of annotation
39399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param list {@code non-null;} the list in question
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static void encodeList(DexFile file, AnnotatedOutput out,
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String label, ArrayList<? extends EncodedMember> list) {
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int size = list.size();
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int lastIndex = 0;
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (size == 0) {
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
403de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (out.annotates()) {
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(0, "  " + label + ":");
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < size; i++) {
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            lastIndex = list.get(i).encode(file, out, lastIndex, i);
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void writeTo0(DexFile file, AnnotatedOutput out) {
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean annotates = out.annotates();
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotates) {
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * The output is to be annotated, so redo the work previously
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * done by place0(), except this time annotations will actually
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * get emitted.
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            encodeOutput(file, out);
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.write(encodedForm);
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
430