Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / third_party / cacheinvalidation / src / java / com / google / ipc / invalidation / ticl / android2 / AndroidStrings.java
1 /*
2  * Copyright 2011 Google Inc.
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 package com.google.ipc.invalidation.ticl.android2;
17
18 import com.google.common.base.Joiner;
19 import com.google.ipc.invalidation.common.CommonProtoStrings2;
20 import com.google.ipc.invalidation.util.TextBuilder;
21 import com.google.protobuf.ByteString;
22 import com.google.protobuf.InvalidProtocolBufferException;
23 import com.google.protos.ipc.invalidation.AndroidService.AndroidNetworkSendRequest;
24 import com.google.protos.ipc.invalidation.AndroidService.AndroidSchedulerEvent;
25 import com.google.protos.ipc.invalidation.AndroidService.ClientDowncall;
26 import com.google.protos.ipc.invalidation.AndroidService.ClientDowncall.AckDowncall;
27 import com.google.protos.ipc.invalidation.AndroidService.ClientDowncall.RegistrationDowncall;
28 import com.google.protos.ipc.invalidation.AndroidService.InternalDowncall;
29 import com.google.protos.ipc.invalidation.AndroidService.InternalDowncall.CreateClient;
30 import com.google.protos.ipc.invalidation.AndroidService.InternalDowncall.NetworkStatus;
31 import com.google.protos.ipc.invalidation.AndroidService.InternalDowncall.ServerMessage;
32 import com.google.protos.ipc.invalidation.AndroidService.ListenerUpcall;
33 import com.google.protos.ipc.invalidation.AndroidService.ListenerUpcall.ErrorUpcall;
34 import com.google.protos.ipc.invalidation.AndroidService.ListenerUpcall.InvalidateUpcall;
35 import com.google.protos.ipc.invalidation.AndroidService.ListenerUpcall.RegistrationFailureUpcall;
36 import com.google.protos.ipc.invalidation.AndroidService.ListenerUpcall.RegistrationStatusUpcall;
37 import com.google.protos.ipc.invalidation.AndroidService.ListenerUpcall.ReissueRegistrationsUpcall;
38 import com.google.protos.ipc.invalidation.Client.AckHandleP;
39 import com.google.protos.ipc.invalidation.ClientProtocol.ObjectIdP;
40
41 import android.content.Intent;
42
43 import java.util.List;
44
45
46 /**
47  * Utilities to format Android protocol buffers and intents as compact strings suitable for logging.
48  * By convention, methods take a {@link TextBuilder} and the object to format and return the
49  * builder. Null object arguments are permitted.
50  *
51  * <p>{@link #toCompactString} methods immediately append a description of the object to the given
52  * {@link TextBuilder}s. {@link #toLazyCompactString} methods return an object that defers the work
53  * of formatting the provided argument until {@link Object#toString} is called.
54  *
55  */
56 public class AndroidStrings {
57
58   /**
59    * String to return when the argument is unknown (suggests a new protocol field or invalid
60    * proto).
61    */
62   static final String UNKNOWN_MESSAGE = "UNKNOWN@AndroidStrings";
63
64   /**
65    * String to return when there is an error formatting an argument.
66    */
67   static final String ERROR_MESSAGE = "ERROR@AndroidStrings";
68
69   /**
70    * Returns an object that lazily evaluates {@link #toCompactString} when {@link Object#toString}
71    * is called.
72    */
73   public static Object toLazyCompactString(final Intent intent) {
74     return new Object() {
75       @Override
76       public String toString() {
77         TextBuilder builder = new TextBuilder();
78         AndroidStrings.toCompactString(builder, intent);
79         return builder.toString();
80       }
81     };
82   }
83
84   /** Appends a description of the given client {@code downcall} to the given {@code builder}. */
85   public static TextBuilder toCompactString(TextBuilder builder,
86       ClientDowncall downcall) {
87     if (downcall == null) {
88       return builder;
89     }
90     builder.append(ProtocolIntents.CLIENT_DOWNCALL_KEY).append("::");
91     if (downcall.hasStart()) {
92       builder.append("start()");
93     } else if (downcall.hasStop()) {
94       builder.append("stop()");
95     } else if (downcall.hasAck()) {
96       toCompactString(builder, downcall.getAck());
97     } else if (downcall.hasRegistrations()) {
98       toCompactString(builder, downcall.getRegistrations());
99     } else {
100       builder.append(UNKNOWN_MESSAGE);
101     }
102     return builder;
103   }
104
105   /** Appends a description of the given {@code ack} downcall to the given {@code builder}. */
106   public static TextBuilder toCompactString(TextBuilder builder, AckDowncall ack) {
107     if (ack == null) {
108       return builder;
109     }
110     builder.append("ack(");
111     serializedAckHandleToCompactString(builder, ack.getAckHandle());
112     return builder.append(")");
113   }
114
115   /**
116    * Appends a description of the given {@code registration} downcall to the given {@code builder}.
117    */
118   public static TextBuilder toCompactString(TextBuilder builder,
119       RegistrationDowncall registration) {
120     if (registration == null) {
121       return builder;
122     }
123     List<ObjectIdP> objects;
124     if (registration.getRegistrationsCount() > 0) {
125       builder.append("register(");
126       objects = registration.getRegistrationsList();
127     } else {
128       builder.append("unregister(");
129       objects = registration.getUnregistrationsList();
130     }
131     return CommonProtoStrings2.toCompactStringForObjectIds(builder, objects).append(")");
132   }
133
134   /** Appends a description of the given internal {@code downcall} to the given {@code builder}. */
135   public static TextBuilder toCompactString(TextBuilder builder,
136       InternalDowncall downcall) {
137     if (downcall == null) {
138       return builder;
139     }
140     builder.append(ProtocolIntents.INTERNAL_DOWNCALL_KEY).append("::");
141     if (downcall.hasServerMessage()) {
142       toCompactString(builder, downcall.getServerMessage());
143     } else if (downcall.hasNetworkStatus()) {
144       toCompactString(builder, downcall.getNetworkStatus());
145     } else if (downcall.hasNetworkAddrChange()) {
146       builder.append("newtworkAddrChange()");
147     } else if (downcall.hasCreateClient()) {
148       toCompactString(builder, downcall.getCreateClient());
149     } else {
150       builder.append(UNKNOWN_MESSAGE);
151     }
152     return builder;
153   }
154
155   /** Appends a description of the given {@code serverMessage} to the given {@code builder}. */
156   public static TextBuilder toCompactString(TextBuilder builder,
157       ServerMessage serverMessage) {
158     if (serverMessage == null) {
159       return builder;
160     }
161     return builder.append("serverMessage(").append(serverMessage.getData()).append(")");
162   }
163
164   /** Appends a description of the given {@code networkStatus} to the given {@code builder}. */
165   public static TextBuilder toCompactString(TextBuilder builder,
166       NetworkStatus networkStatus) {
167     if (networkStatus == null) {
168       return builder;
169     }
170     return builder.append("networkStatus(isOnline = ").append(networkStatus.getIsOnline())
171         .append(")");
172   }
173
174   /**
175    * Appends a description of the given {@code createClient} command to the given {@code builder}.
176    */
177   public static TextBuilder toCompactString(TextBuilder builder,
178       CreateClient createClient) {
179     if (createClient == null) {
180       return builder;
181     }
182     return builder.append("createClient(type = ").append(createClient.getClientType())
183         .append(", name = ").append(createClient.getClientName()).append(", skipStartForTest = ")
184         .append(createClient.getSkipStartForTest()).append(")");
185   }
186
187   /** Appends a description of the given listener {@code upcall} to the given {@code builder}. */
188   public static TextBuilder toCompactString(TextBuilder builder,
189       ListenerUpcall upcall) {
190     if (upcall == null) {
191        return builder;
192     }
193     builder.append(ProtocolIntents.LISTENER_UPCALL_KEY).append("::");
194     if (upcall.hasReady()) {
195       builder.append(".ready()");
196     } else if (upcall.hasInvalidate()) {
197       toCompactString(builder, upcall.getInvalidate());
198     } else if (upcall.hasRegistrationStatus()) {
199       toCompactString(builder, upcall.getRegistrationStatus());
200     } else if (upcall.hasRegistrationFailure()) {
201       toCompactString(builder, upcall.getRegistrationFailure());
202     } else if (upcall.hasReissueRegistrations()) {
203       toCompactString(builder, upcall.getReissueRegistrations());
204     } else if (upcall.hasError()) {
205       toCompactString(builder, upcall.getError());
206     } else {
207       builder.append(UNKNOWN_MESSAGE);
208     }
209     return builder;
210   }
211
212   /** Appends a description of the given {@code invalidate} command to the given {@code builder}. */
213   public static TextBuilder toCompactString(TextBuilder builder,
214       InvalidateUpcall invalidate) {
215     if (invalidate == null) {
216       return builder;
217     }
218     builder.append("invalidate(ackHandle = ");
219     serializedAckHandleToCompactString(builder, invalidate.getAckHandle());
220     builder.append(", ");
221     if (invalidate.hasInvalidation()) {
222       CommonProtoStrings2.toCompactString(builder, invalidate.getInvalidation());
223     } else if (invalidate.getInvalidateAll()) {
224       builder.append("ALL");
225     } else if (invalidate.hasInvalidateUnknown()) {
226       builder.append("UNKNOWN: ");
227       CommonProtoStrings2.toCompactString(builder, invalidate.getInvalidateUnknown());
228     }
229     return builder.append(")");
230   }
231
232   /** Appends a description of the given {@code status} upcall to the given {@code builder}. */
233   public static TextBuilder toCompactString(TextBuilder builder,
234       RegistrationStatusUpcall status) {
235     if (status == null) {
236       return builder;
237     }
238     builder.append("registrationStatus(objectId = ");
239     CommonProtoStrings2.toCompactString(builder, status.getObjectId());
240     return builder.append(", isRegistered = ").append(status.getIsRegistered()).append(")");
241   }
242
243   /** Appends a description of the given {@code failure} upcall to the given {@code builder}. */
244   public static TextBuilder toCompactString(TextBuilder builder,
245       RegistrationFailureUpcall failure) {
246     if (failure == null) {
247       return builder;
248     }
249     builder.append("registrationFailure(objectId = ");
250     CommonProtoStrings2.toCompactString(builder, failure.getObjectId());
251     return builder.append(", isTransient = ").append(failure.getTransient()).append(")");
252   }
253
254   /**
255    * Appends a description of the given {@code reissue} registrations upcall to the given
256    * {@code builder}.
257    */
258   public static TextBuilder toCompactString(TextBuilder builder,
259       ReissueRegistrationsUpcall reissue) {
260     if (reissue == null) {
261       return builder;
262     }
263     builder.append("reissueRegistrations(prefix = ");
264     return builder.append(reissue.getPrefix()).append(", length = ").append(reissue.getLength())
265         .append(")");
266   }
267
268   /** Appends a description of the given {@code error} upcall to the given {@code builder}. */
269   public static TextBuilder toCompactString(TextBuilder builder, ErrorUpcall error) {
270     if (error == null) {
271       return builder;
272     }
273     return builder.append("error(code = ").append(error.getErrorCode()).append(", message = ")
274         .append(error.getErrorMessage()).append(", isTransient = ").append(error.getIsTransient())
275         .append(")");
276   }
277
278   /** Appends a description of the given {@code request} to the given {@code builder}. */
279   public static TextBuilder toCompactString(TextBuilder builder,
280       AndroidNetworkSendRequest request) {
281     if (request == null) {
282       return builder;
283     }
284     return builder.append(ProtocolIntents.OUTBOUND_MESSAGE_KEY).append("(")
285         .append(request.getMessage()).append(")");
286   }
287
288   /** Appends a description of the given (@code event} to the given {@code builder}. */
289   public static TextBuilder toCompactString(TextBuilder builder,
290       AndroidSchedulerEvent event) {
291     if (event == null) {
292       return builder;
293     }
294     return builder.append(ProtocolIntents.SCHEDULER_KEY).append("(eventName = ")
295         .append(event.getEventName()).append(", ticlId = ").append(event.getTiclId()).append(")");
296   }
297
298   /** See spec in implementation notes. */
299   public static TextBuilder toCompactString(TextBuilder builder, AckHandleP ackHandle) {
300     if (ackHandle == null) {
301       return builder;
302     }
303     return CommonProtoStrings2.toCompactString(builder.appendFormat("AckHandle: "),
304         ackHandle.getInvalidation());
305   }
306
307   /**
308    * Appends a description of the given {@code intent} to the given {@code builder}. If the intent
309    * includes some recognized extras, formats the extra context as well.
310    */
311   public static TextBuilder toCompactString(TextBuilder builder, Intent intent) {
312     if (intent == null) {
313       return builder;
314     }
315     builder.append("intent(");
316     try {
317       if (!tryParseExtra(builder, intent)) {
318         builder.append(UNKNOWN_MESSAGE).append(", extras = ")
319             .append(Joiner.on(", ").join(intent.getExtras().keySet()));
320       }
321     } catch (InvalidProtocolBufferException exception) {
322       builder.append(ERROR_MESSAGE).append(" : ").append(exception);
323     }
324     return builder.append(")");
325   }
326
327   /** Appends a description of any known extra or appends 'UNKNOWN' if none are recognized. */
328   private static boolean tryParseExtra(TextBuilder builder, Intent intent)
329       throws InvalidProtocolBufferException {
330     byte[] data;
331
332     data = intent.getByteArrayExtra(ProtocolIntents.SCHEDULER_KEY);
333     if (data != null) {
334       AndroidSchedulerEvent schedulerEvent = AndroidSchedulerEvent.parseFrom(data);
335       toCompactString(builder, schedulerEvent);
336       return true;
337     }
338
339     data = intent.getByteArrayExtra(ProtocolIntents.OUTBOUND_MESSAGE_KEY);
340     if (data != null) {
341       AndroidNetworkSendRequest outboundMessage = AndroidNetworkSendRequest.parseFrom(data);
342       toCompactString(builder, outboundMessage);
343       return true;
344     }
345
346     data = intent.getByteArrayExtra(ProtocolIntents.LISTENER_UPCALL_KEY);
347     if (data != null) {
348       ListenerUpcall upcall = ListenerUpcall.parseFrom(data);
349       toCompactString(builder, upcall);
350       return true;
351     }
352
353     data = intent.getByteArrayExtra(ProtocolIntents.INTERNAL_DOWNCALL_KEY);
354     if (data != null) {
355       InternalDowncall internalDowncall = InternalDowncall.parseFrom(data);
356       toCompactString(builder, internalDowncall);
357       return true;
358     }
359
360     data = intent.getByteArrayExtra(ProtocolIntents.CLIENT_DOWNCALL_KEY);
361     if (data != null) {
362       ClientDowncall clientDowncall = ClientDowncall.parseFrom(data);
363       toCompactString(builder, clientDowncall);
364       return true;
365     }
366
367     // Didn't recognize any intents.
368     return false;
369   }
370
371   /** Given serialized form of an ack handle, appends description to {@code builder}. */
372   private static TextBuilder serializedAckHandleToCompactString(
373       TextBuilder builder, ByteString serialized) {
374     if (serialized == null) {
375       return builder;
376     }
377     // The ack handle is supposed by an AckHandleP!
378     try {
379       AckHandleP ackHandle = AckHandleP.parseFrom(serialized);
380       return toCompactString(builder, ackHandle);
381     } catch (InvalidProtocolBufferException exception) {
382       // But it wasn't... Just log the raw bytes.
383       return builder.append(serialized);
384     }
385   }
386
387   private AndroidStrings() {
388     // Avoid instantiation.
389   }
390 }