1/*
2 * Copyright (C) 2016 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 */
16package android.hardware.location;
17
18import android.annotation.SystemApi;
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.util.Log;
22
23/** A class describing nano apps.
24 * A nano app is a piece of executable code that can be
25 * downloaded onto a specific architecture. These are targtted
26 * for low power compute domains on a device.
27 *
28 * Nano apps are expected to be used only by bundled apps only
29 * at this time.
30 *
31 * @hide
32 */
33@SystemApi
34public class NanoApp {
35    private final String TAG = "NanoApp";
36
37    private final String UNKNOWN = "Unknown";
38
39    private String mPublisher;
40    private String mName;
41
42    private int mAppId;
43    private boolean mAppIdSet;
44    private int mAppVersion;
45
46    private int mNeededReadMemBytes;
47    private int mNeededWriteMemBytes;
48    private int mNeededExecMemBytes;
49
50    private int[] mNeededSensors;
51    private int[] mOutputEvents;
52    private byte[] mAppBinary;
53
54    /**
55     * If this version of the constructor is used, the methods
56     * {@link #setAppBinary(byte[])} and {@link #setAppId(int)} must be called
57     * prior to passing this object to any managers.
58     *
59     * @see #NanoApp(int, byte[])
60     */
61    public NanoApp() {
62        this(0, null);
63        mAppIdSet = false;
64    }
65
66    /**
67     * Initialize a NanoApp with the given id and binary.
68     *
69     * While this sets defaults for other fields, users will want to provide
70     * other values for those fields in most cases.
71     *
72     * @see #setPublisher(String)
73     * @see #setName(String)
74     * @see #setAppVersion(int)
75     * @see #setNeededReadMemBytes(int)
76     * @see #setNeededWriteMemBytes(int)
77     * @see #setNeededExecMemBytes(int)
78     * @see #setNeededSensors(int[])
79     * @see #setOutputEvents(int[])
80     */
81    public NanoApp(int appId, byte[] appBinary) {
82        mPublisher = UNKNOWN;
83        mName = UNKNOWN;
84
85        mAppId = appId;
86        mAppIdSet = true;
87        mAppVersion = 0;
88
89        mNeededReadMemBytes = 0;
90        mNeededWriteMemBytes = 0;
91        mNeededExecMemBytes = 0;
92
93        mNeededSensors = new int[0];
94        mOutputEvents = new int[0];
95        mAppBinary = appBinary;
96    }
97
98    /**
99     * Set the publisher name
100     *
101     * @param publisher name of the publisher of this nano app
102     */
103    public void setPublisher(String publisher) {
104        mPublisher = publisher;
105    }
106
107    /**
108     * set the name of the app
109     *
110     * @param name   name of the app
111     */
112    public void setName(String name) {
113        mName = name;
114    }
115
116    /**
117     * set the app identifier
118     *
119     * @param appId  add identifier
120     */
121    public void setAppId(int appId) {
122        mAppId = appId;
123        mAppIdSet = true;
124    }
125
126    /**
127     * Set the app version
128     *
129     * @param appVersion app version
130     */
131    public void setAppVersion(int appVersion) {
132        mAppVersion = appVersion;
133    }
134
135    /**
136     * set memory needed as read only
137     *
138     * @param neededReadMemBytes
139     *               read only memory needed in bytes
140     */
141    public void setNeededReadMemBytes(int neededReadMemBytes) {
142        mNeededReadMemBytes = neededReadMemBytes;
143    }
144
145    /**
146     * set writable memory needed in bytes
147     *
148     * @param neededWriteMemBytes
149     *               writable memory needed in bytes
150     */
151    public void setNeededWriteMemBytes(int neededWriteMemBytes) {
152        mNeededWriteMemBytes = neededWriteMemBytes;
153    }
154
155    /**
156     * set executable memory needed
157     *
158     * @param neededExecMemBytes
159     *               executable memory needed in bytes
160     */
161    public void setNeededExecMemBytes(int neededExecMemBytes) {
162        mNeededExecMemBytes = neededExecMemBytes;
163    }
164
165    /**
166     * set the sensors needed for this app
167     *
168     * @param neededSensors
169     *               needed Sensors
170     */
171    public void setNeededSensors(int[] neededSensors) {
172        mNeededSensors = neededSensors;
173    }
174
175    public void setOutputEvents(int[] outputEvents) {
176        mOutputEvents = outputEvents;
177    }
178
179    /**
180     * set output events returned by the nano app
181     *
182     * @param appBinary generated events
183     */
184    public void setAppBinary(byte[] appBinary) {
185        mAppBinary = appBinary;
186    }
187
188
189    /**
190     * get the publisher name
191     *
192     * @return publisher name
193     */
194    public String getPublisher() {
195        return mPublisher;
196    }
197
198    /**
199     * get the name of the app
200     *
201     * @return app name
202     */
203    public String getName() {
204        return mName;
205    }
206
207    /**
208     * get the identifier of the app
209     *
210     * @return identifier for this app
211     */
212    public int getAppId() {
213        return mAppId;
214    }
215
216    /**
217     * get the app version
218     *
219     * @return app version
220     */
221    public int getAppVersion() {
222        return mAppVersion;
223    }
224
225    /**
226     * get the ammount of readable memory needed by this app
227     *
228     * @return readable memory needed in bytes
229     */
230    public int getNeededReadMemBytes() {
231        return mNeededReadMemBytes;
232    }
233
234    /**
235     * get the ammount og writable memory needed in bytes
236     *
237     * @return writable memory needed in bytes
238     */
239    public int getNeededWriteMemBytes() {
240        return mNeededWriteMemBytes;
241    }
242
243    /**
244     * executable memory needed in bytes
245     *
246     * @return executable memory needed in bytes
247     */
248    public int getNeededExecMemBytes() {
249        return mNeededExecMemBytes;
250    }
251
252    /**
253     * get the sensors needed by this app
254     *
255     * @return sensors needed
256     */
257    public int[] getNeededSensors() {
258        return mNeededSensors;
259    }
260
261    /**
262     * get the events generated by this app
263     *
264     * @return generated events
265     */
266    public int[] getOutputEvents() {
267        return mOutputEvents;
268    }
269
270    /**
271     * get the binary for this app
272     *
273     * @return app binary
274     */
275    public byte[] getAppBinary() {
276        return mAppBinary;
277    }
278
279    private NanoApp(Parcel in) {
280        mPublisher = in.readString();
281        mName = in.readString();
282
283        mAppId = in.readInt();
284        mAppVersion = in.readInt();
285        mNeededReadMemBytes = in.readInt();
286        mNeededWriteMemBytes = in.readInt();
287        mNeededExecMemBytes = in.readInt();
288
289        int mNeededSensorsLength = in.readInt();
290        mNeededSensors = new int[mNeededSensorsLength];
291        in.readIntArray(mNeededSensors);
292
293        int mOutputEventsLength = in.readInt();
294        mOutputEvents = new int[mOutputEventsLength];
295        in.readIntArray(mOutputEvents);
296
297        int binaryLength = in.readInt();
298        mAppBinary = new byte[binaryLength];
299        in.readByteArray(mAppBinary);
300    }
301
302    public int describeContents() {
303        return 0;
304    }
305
306    public void writeToParcel(Parcel out, int flags) {
307        if (mAppBinary == null) {
308            throw new IllegalStateException("Must set non-null AppBinary for nanoapp " + mName);
309        }
310        if (!mAppIdSet) {
311            throw new IllegalStateException("Must set AppId for nanoapp " + mName);
312        }
313
314        out.writeString(mPublisher);
315        out.writeString(mName);
316        out.writeInt(mAppId);
317        out.writeInt(mAppVersion);
318        out.writeInt(mNeededReadMemBytes);
319        out.writeInt(mNeededWriteMemBytes);
320        out.writeInt(mNeededExecMemBytes);
321
322        out.writeInt(mNeededSensors.length);
323        out.writeIntArray(mNeededSensors);
324
325        out.writeInt(mOutputEvents.length);
326        out.writeIntArray(mOutputEvents);
327
328        out.writeInt(mAppBinary.length);
329        out.writeByteArray(mAppBinary);
330    }
331
332    public static final Parcelable.Creator<NanoApp> CREATOR
333            = new Parcelable.Creator<NanoApp>() {
334        public NanoApp createFromParcel(Parcel in) {
335            return new NanoApp(in);
336        }
337
338        public NanoApp[] newArray(int size) {
339            return new NanoApp[size];
340        }
341    };
342
343    @Override
344    public String toString() {
345        String retVal = "Id : " + mAppId;
346        retVal += ", Version : " + mAppVersion;
347        retVal += ", Name : " + mName;
348        retVal += ", Publisher : " + mPublisher;
349
350        return retVal;
351    }
352}
353