1 /*
2  * Copyright (C) 2015 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 
17 package android.service.gatekeeper;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 import com.android.internal.annotations.VisibleForTesting;
23 
24 /**
25  * Response object for a GateKeeper verification request.
26  * @hide
27  */
28 public final class GateKeeperResponse implements Parcelable {
29 
30     public static final int RESPONSE_ERROR = -1;
31     public static final int RESPONSE_OK = 0;
32     public static final int RESPONSE_RETRY = 1;
33 
34     private final int mResponseCode;
35 
36     private int mTimeout;
37     private byte[] mPayload;
38     private boolean mShouldReEnroll;
39 
40     /** Default constructor for response with generic response code **/
GateKeeperResponse(int responseCode)41     private GateKeeperResponse(int responseCode) {
42         mResponseCode = responseCode;
43     }
44 
45     @VisibleForTesting
createGenericResponse(int responseCode)46     public static GateKeeperResponse createGenericResponse(int responseCode) {
47         return new GateKeeperResponse(responseCode);
48     }
49 
createRetryResponse(int timeout)50     private static GateKeeperResponse createRetryResponse(int timeout) {
51         GateKeeperResponse response = new GateKeeperResponse(RESPONSE_RETRY);
52         response.mTimeout = timeout;
53         return response;
54     }
55 
56     @VisibleForTesting
createOkResponse(byte[] payload, boolean shouldReEnroll)57     public static GateKeeperResponse createOkResponse(byte[] payload, boolean shouldReEnroll) {
58         GateKeeperResponse response = new GateKeeperResponse(RESPONSE_OK);
59         response.mPayload = payload;
60         response.mShouldReEnroll = shouldReEnroll;
61         return response;
62     }
63 
64     @Override
describeContents()65     public int describeContents() {
66         return 0;
67     }
68 
69     public static final @android.annotation.NonNull Parcelable.Creator<GateKeeperResponse> CREATOR
70             = new Parcelable.Creator<GateKeeperResponse>() {
71         @Override
72         public GateKeeperResponse createFromParcel(Parcel source) {
73             int responseCode = source.readInt();
74             final GateKeeperResponse response;
75             if (responseCode == RESPONSE_RETRY) {
76                 response = createRetryResponse(source.readInt());
77             } else if (responseCode == RESPONSE_OK) {
78                 final boolean shouldReEnroll = source.readInt() == 1;
79                 byte[] payload = null;
80                 int size = source.readInt();
81                 if (size > 0) {
82                     payload = new byte[size];
83                     source.readByteArray(payload);
84                 }
85                 response = createOkResponse(payload, shouldReEnroll);
86             } else {
87                 response = createGenericResponse(responseCode);
88             }
89             return response;
90         }
91 
92         @Override
93         public GateKeeperResponse[] newArray(int size) {
94             return new GateKeeperResponse[size];
95         }
96 
97     };
98 
99     @Override
writeToParcel(Parcel dest, int flags)100     public void writeToParcel(Parcel dest, int flags) {
101         dest.writeInt(mResponseCode);
102         if (mResponseCode == RESPONSE_RETRY) {
103             dest.writeInt(mTimeout);
104         } else if (mResponseCode == RESPONSE_OK) {
105             dest.writeInt(mShouldReEnroll ? 1 : 0);
106             if (mPayload != null) {
107                 dest.writeInt(mPayload.length);
108                 dest.writeByteArray(mPayload);
109             } else {
110                 dest.writeInt(0);
111             }
112         }
113     }
114 
getPayload()115     public byte[] getPayload() {
116         return mPayload;
117     }
118 
getTimeout()119     public int getTimeout() {
120         return mTimeout;
121     }
122 
getShouldReEnroll()123     public boolean getShouldReEnroll() {
124         return mShouldReEnroll;
125     }
126 
getResponseCode()127     public int getResponseCode() {
128         return mResponseCode;
129     }
130 }
131