blob: d5e9f660279f4d60e86027ac1982fab98091fb5e [file] [log] [blame]
Jeff Sharkey31c6e482011-11-18 17:09:01 -08001/*
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;
18
Jeff Sharkeyba2896e2011-11-30 18:13:54 -080019import com.google.android.collect.Lists;
20
21import java.util.ArrayList;
22
Jeff Sharkey31c6e482011-11-18 17:09:01 -080023/**
24 * Parsed event from native side of {@link NativeDaemonConnector}.
25 */
26public class NativeDaemonEvent {
27
28 // TODO: keep class ranges in sync with ResponseCode.h
29 // TODO: swap client and server error ranges to roughly mirror HTTP spec
30
Robert Greenwalt470007f2012-02-07 11:36:55 -080031 private final int mCmdNumber;
Jeff Sharkey31c6e482011-11-18 17:09:01 -080032 private final int mCode;
33 private final String mMessage;
34 private final String mRawEvent;
35
Robert Greenwalt470007f2012-02-07 11:36:55 -080036 private NativeDaemonEvent(int cmdNumber, int code, String message, String rawEvent) {
37 mCmdNumber = cmdNumber;
Jeff Sharkey31c6e482011-11-18 17:09:01 -080038 mCode = code;
39 mMessage = message;
40 mRawEvent = rawEvent;
41 }
42
Robert Greenwalt470007f2012-02-07 11:36:55 -080043 public int getCmdNumber() {
44 return mCmdNumber;
45 }
46
Jeff Sharkey31c6e482011-11-18 17:09:01 -080047 public int getCode() {
48 return mCode;
49 }
50
51 public String getMessage() {
52 return mMessage;
53 }
54
55 @Deprecated
56 public String getRawEvent() {
57 return mRawEvent;
58 }
59
60 @Override
61 public String toString() {
62 return mRawEvent;
63 }
64
65 /**
66 * Test if event represents a partial response which is continued in
67 * additional subsequent events.
68 */
69 public boolean isClassContinue() {
70 return mCode >= 100 && mCode < 200;
71 }
72
73 /**
74 * Test if event represents a command success.
75 */
76 public boolean isClassOk() {
77 return mCode >= 200 && mCode < 300;
78 }
79
80 /**
81 * Test if event represents a remote native daemon error.
82 */
83 public boolean isClassServerError() {
84 return mCode >= 400 && mCode < 500;
85 }
86
87 /**
88 * Test if event represents a command syntax or argument error.
89 */
90 public boolean isClassClientError() {
91 return mCode >= 500 && mCode < 600;
92 }
93
94 /**
95 * Test if event represents an unsolicited event from native daemon.
96 */
97 public boolean isClassUnsolicited() {
Robert Greenwalt470007f2012-02-07 11:36:55 -080098 return isClassUnsolicited(mCode);
99 }
100
101 private static boolean isClassUnsolicited(int code) {
102 return code >= 600 && code < 700;
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800103 }
104
105 /**
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800106 * Verify this event matches the given code.
107 *
108 * @throws IllegalStateException if {@link #getCode()} doesn't match.
109 */
110 public void checkCode(int code) {
111 if (mCode != code) {
112 throw new IllegalStateException("Expected " + code + " but was: " + this);
113 }
114 }
115
116 /**
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800117 * Parse the given raw event into {@link NativeDaemonEvent} instance.
118 *
119 * @throws IllegalArgumentException when line doesn't match format expected
120 * from native side.
121 */
122 public static NativeDaemonEvent parseRawEvent(String rawEvent) {
Robert Greenwalt470007f2012-02-07 11:36:55 -0800123 final String[] parsed = rawEvent.split(" ");
124 if (parsed.length < 2) {
125 throw new IllegalArgumentException("Insufficient arguments");
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800126 }
127
Robert Greenwalt470007f2012-02-07 11:36:55 -0800128 int skiplength = 0;
129
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800130 final int code;
131 try {
Robert Greenwalt470007f2012-02-07 11:36:55 -0800132 code = Integer.parseInt(parsed[0]);
133 skiplength = parsed[0].length() + 1;
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800134 } catch (NumberFormatException e) {
135 throw new IllegalArgumentException("problem parsing code", e);
136 }
137
Robert Greenwalt470007f2012-02-07 11:36:55 -0800138 int cmdNumber = -1;
139 if (isClassUnsolicited(code) == false) {
140 if (parsed.length < 3) {
141 throw new IllegalArgumentException("Insufficient arguemnts");
142 }
143 try {
144 cmdNumber = Integer.parseInt(parsed[1]);
145 skiplength += parsed[1].length() + 1;
146 } catch (NumberFormatException e) {
147 throw new IllegalArgumentException("problem parsing cmdNumber", e);
148 }
149 }
150
151 final String message = rawEvent.substring(skiplength);
152
153 return new NativeDaemonEvent(cmdNumber, code, message, rawEvent);
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800154 }
Jeff Sharkeyba2896e2011-11-30 18:13:54 -0800155
156 /**
157 * Filter the given {@link NativeDaemonEvent} list, returning
158 * {@link #getMessage()} for any events matching the requested code.
159 */
160 public static String[] filterMessageList(NativeDaemonEvent[] events, int matchCode) {
161 final ArrayList<String> result = Lists.newArrayList();
162 for (NativeDaemonEvent event : events) {
163 if (event.getCode() == matchCode) {
164 result.add(event.getMessage());
165 }
166 }
167 return result.toArray(new String[result.size()]);
168 }
Jeff Sharkey31c6e482011-11-18 17:09:01 -0800169}