1/*
2 * Copyright (C) 2005 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 android.os;
18
19import android.annotation.SystemApi;
20import android.annotation.TestApi;
21import android.content.Intent;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.util.IntArray;
25
26import java.util.ArrayList;
27
28/**
29 * The arguments for an incident report.
30 * {@hide}
31 */
32@SystemApi
33@TestApi
34public final class IncidentReportArgs implements Parcelable {
35
36    private final IntArray mSections = new IntArray();
37    private final ArrayList<byte[]> mHeaders = new ArrayList<byte[]>();
38    private boolean mAll;
39
40    /**
41     * Construct an incident report args with no fields.
42     */
43    public IncidentReportArgs() {
44    }
45
46    /**
47     * Construct an incdent report args from the given parcel.
48     */
49    public IncidentReportArgs(Parcel in) {
50        readFromParcel(in);
51    }
52
53    public int describeContents() {
54        return 0;
55    }
56
57    public void writeToParcel(Parcel out, int flags) {
58        out.writeInt(mAll ? 1 : 0);
59
60        int N = mSections.size();
61        out.writeInt(N);
62        for (int i=0; i<N; i++) {
63            out.writeInt(mSections.get(i));
64        }
65
66        N = mHeaders.size();
67        out.writeInt(N);
68        for (int i=0; i<N; i++) {
69            out.writeByteArray(mHeaders.get(i));
70        }
71    }
72
73    public void readFromParcel(Parcel in) {
74        mAll = in.readInt() != 0;
75
76        mSections.clear();
77        int N = in.readInt();
78        for (int i=0; i<N; i++) {
79            mSections.add(in.readInt());
80        }
81
82        mHeaders.clear();
83        N = in.readInt();
84        for (int i=0; i<N; i++) {
85            mHeaders.add(in.createByteArray());
86        }
87    }
88
89    public static final Parcelable.Creator<IncidentReportArgs> CREATOR
90            = new Parcelable.Creator<IncidentReportArgs>() {
91        public IncidentReportArgs createFromParcel(Parcel in) {
92            return new IncidentReportArgs(in);
93        }
94
95        public IncidentReportArgs[] newArray(int size) {
96            return new IncidentReportArgs[size];
97        }
98    };
99
100    /**
101     * Print this report as a string.
102     */
103    public String toString() {
104        final StringBuilder sb = new StringBuilder("Incident(");
105        if (mAll) {
106            sb.append("all");
107        } else {
108            final int N = mSections.size();
109            if (N > 0) {
110                sb.append(mSections.get(0));
111            }
112            for (int i=1; i<N; i++) {
113                sb.append(" ");
114                sb.append(mSections.get(i));
115            }
116        }
117        sb.append(", ");
118        sb.append(mHeaders.size());
119        sb.append(" headers)");
120        return sb.toString();
121    }
122
123    /**
124     * Set this incident report to include all fields.
125     */
126    public void setAll(boolean all) {
127        mAll = all;
128        if (all) {
129            mSections.clear();
130        }
131    }
132
133    /**
134     * Add this section to the incident report.
135     */
136    public void addSection(int section) {
137        if (!mAll) {
138            mSections.add(section);
139        }
140    }
141
142    /**
143     * Returns whether the incident report will include all fields.
144     */
145    public boolean isAll() {
146        return mAll;
147    }
148
149    /**
150     * Returns whether this section will be included in the incident report.
151     */
152    public boolean containsSection(int section) {
153        return mAll || mSections.indexOf(section) >= 0;
154    }
155
156    public int sectionCount() {
157        return mSections.size();
158    }
159
160    public void addHeader(byte[] header) {
161        mHeaders.add(header);
162    }
163
164    /**
165     * Parses an incident report config as described in the system setting.
166     *
167     * @see IncidentManager#reportIncident
168     */
169    public static IncidentReportArgs parseSetting(String setting)
170            throws IllegalArgumentException {
171        if (setting == null || setting.length() == 0) {
172            return null;
173        }
174        setting = setting.trim();
175        if (setting.length() == 0 || "disabled".equals(setting)) {
176            return null;
177        }
178
179        final IncidentReportArgs args = new IncidentReportArgs();
180
181        if ("all".equals(setting)) {
182            args.setAll(true);
183            return args;
184        } else if ("none".equals(setting)) {
185            return args;
186        }
187
188        final String[] splits = setting.split(",");
189        final int N = splits.length;
190        for (int i=0; i<N; i++) {
191            final String str = splits[i].trim();
192            if (str.length() == 0) {
193                continue;
194            }
195            int section;
196            try {
197                section = Integer.parseInt(str);
198            } catch (NumberFormatException ex) {
199                throw new IllegalArgumentException("Malformed setting. Bad integer at section"
200                        + " index " + i + ": section='" + str + "' setting='" + setting + "'");
201            }
202            if (section < 1) {
203                throw new IllegalArgumentException("Malformed setting. Illegal section at"
204                        + " index " + i + ": section='" + str + "' setting='" + setting + "'");
205            }
206            args.addSection(section);
207        }
208
209        return args;
210    }
211}
212
213