blob: f5c81e4c2ea82b4730d5cf1342d1de39ead470ae [file] [log] [blame]
Kenny Rootcf0b38c2011-03-22 14:17:59 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import com.android.internal.util.XmlUtils;
20
21import org.xmlpull.v1.XmlPullParser;
22import org.xmlpull.v1.XmlPullParserException;
23import org.xmlpull.v1.XmlSerializer;
24
25import android.content.pm.Signature;
26import android.util.Log;
27
28import java.io.IOException;
29import java.util.ArrayList;
30
31class PackageSignatures {
32 Signature[] mSignatures;
33
34 PackageSignatures(PackageSignatures orig) {
35 if (orig != null && orig.mSignatures != null) {
36 mSignatures = orig.mSignatures.clone();
37 }
38 }
39
40 PackageSignatures(Signature[] sigs) {
41 assignSignatures(sigs);
42 }
43
44 PackageSignatures() {
45 }
46
47 void writeXml(XmlSerializer serializer, String tagName,
48 ArrayList<Signature> pastSignatures) throws IOException {
49 if (mSignatures == null) {
50 return;
51 }
52 serializer.startTag(null, tagName);
53 serializer.attribute(null, "count",
54 Integer.toString(mSignatures.length));
55 for (int i=0; i<mSignatures.length; i++) {
56 serializer.startTag(null, "cert");
57 final Signature sig = mSignatures[i];
58 final int sigHash = sig.hashCode();
59 final int numPast = pastSignatures.size();
60 int j;
61 for (j=0; j<numPast; j++) {
62 Signature pastSig = pastSignatures.get(j);
63 if (pastSig.hashCode() == sigHash && pastSig.equals(sig)) {
64 serializer.attribute(null, "index", Integer.toString(j));
65 break;
66 }
67 }
68 if (j >= numPast) {
69 pastSignatures.add(sig);
70 serializer.attribute(null, "index", Integer.toString(numPast));
71 serializer.attribute(null, "key", sig.toCharsString());
72 }
73 serializer.endTag(null, "cert");
74 }
75 serializer.endTag(null, tagName);
76 }
77
78 void readXml(XmlPullParser parser, ArrayList<Signature> pastSignatures)
79 throws IOException, XmlPullParserException {
80 String countStr = parser.getAttributeValue(null, "count");
81 if (countStr == null) {
82 PackageManagerService.reportSettingsProblem(Log.WARN,
83 "Error in package manager settings: <signatures> has"
84 + " no count at " + parser.getPositionDescription());
85 XmlUtils.skipCurrentTag(parser);
86 }
87 final int count = Integer.parseInt(countStr);
88 mSignatures = new Signature[count];
89 int pos = 0;
90
91 int outerDepth = parser.getDepth();
92 int type;
93 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
94 && (type != XmlPullParser.END_TAG
95 || parser.getDepth() > outerDepth)) {
96 if (type == XmlPullParser.END_TAG
97 || type == XmlPullParser.TEXT) {
98 continue;
99 }
100
101 String tagName = parser.getName();
102 if (tagName.equals("cert")) {
103 if (pos < count) {
104 String index = parser.getAttributeValue(null, "index");
105 if (index != null) {
106 try {
107 int idx = Integer.parseInt(index);
108 String key = parser.getAttributeValue(null, "key");
109 if (key == null) {
110 if (idx >= 0 && idx < pastSignatures.size()) {
111 Signature sig = pastSignatures.get(idx);
112 if (sig != null) {
113 mSignatures[pos] = pastSignatures.get(idx);
114 pos++;
115 } else {
116 PackageManagerService.reportSettingsProblem(Log.WARN,
117 "Error in package manager settings: <cert> "
118 + "index " + index + " is not defined at "
119 + parser.getPositionDescription());
120 }
121 } else {
122 PackageManagerService.reportSettingsProblem(Log.WARN,
123 "Error in package manager settings: <cert> "
124 + "index " + index + " is out of bounds at "
125 + parser.getPositionDescription());
126 }
127 } else {
128 while (pastSignatures.size() <= idx) {
129 pastSignatures.add(null);
130 }
131 Signature sig = new Signature(key);
132 pastSignatures.set(idx, sig);
133 mSignatures[pos] = sig;
134 pos++;
135 }
136 } catch (NumberFormatException e) {
137 PackageManagerService.reportSettingsProblem(Log.WARN,
138 "Error in package manager settings: <cert> "
139 + "index " + index + " is not a number at "
140 + parser.getPositionDescription());
Kenny Root11373412011-07-28 15:13:33 -0700141 } catch (IllegalArgumentException e) {
142 PackageManagerService.reportSettingsProblem(Log.WARN,
143 "Error in package manager settings: <cert> "
144 + "index " + index + " has an invalid signature at "
145 + parser.getPositionDescription() + ": "
146 + e.getMessage());
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700147 }
148 } else {
149 PackageManagerService.reportSettingsProblem(Log.WARN,
150 "Error in package manager settings: <cert> has"
151 + " no index at " + parser.getPositionDescription());
152 }
153 } else {
154 PackageManagerService.reportSettingsProblem(Log.WARN,
155 "Error in package manager settings: too "
156 + "many <cert> tags, expected " + count
157 + " at " + parser.getPositionDescription());
158 }
159 } else {
160 PackageManagerService.reportSettingsProblem(Log.WARN,
161 "Unknown element under <cert>: "
162 + parser.getName());
163 }
164 XmlUtils.skipCurrentTag(parser);
165 }
166
167 if (pos < count) {
168 // Should never happen -- there is an error in the written
169 // settings -- but if it does we don't want to generate
170 // a bad array.
171 Signature[] newSigs = new Signature[pos];
172 System.arraycopy(mSignatures, 0, newSigs, 0, pos);
173 mSignatures = newSigs;
174 }
175 }
176
177 void assignSignatures(Signature[] sigs) {
178 if (sigs == null) {
179 mSignatures = null;
180 return;
181 }
182 mSignatures = new Signature[sigs.length];
183 for (int i=0; i<sigs.length; i++) {
184 mSignatures[i] = sigs[i];
185 }
186 }
187
188 @Override
189 public String toString() {
190 StringBuffer buf = new StringBuffer(128);
191 buf.append("PackageSignatures{");
192 buf.append(Integer.toHexString(System.identityHashCode(this)));
193 buf.append(" [");
194 if (mSignatures != null) {
195 for (int i=0; i<mSignatures.length; i++) {
196 if (i > 0) buf.append(", ");
197 buf.append(Integer.toHexString(
Svet Ganov354cd3c2015-12-17 11:35:04 -0800198 mSignatures[i].hashCode()));
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700199 }
200 }
201 buf.append("]}");
202 return buf.toString();
203 }
204}