Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / cacheinvalidation / src / java / com / google / ipc / invalidation / ticl / android2 / channel / AndroidMessageReceiverService.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.channel;
17
18 import com.google.android.gcm.GCMRegistrar;
19 import com.google.ipc.invalidation.external.client.SystemResources.Logger;
20 import com.google.ipc.invalidation.external.client.android.service.AndroidLogger;
21 import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener;
22 import com.google.ipc.invalidation.ticl.android2.AndroidTiclManifest;
23 import com.google.ipc.invalidation.ticl.android2.ProtocolIntents;
24 import com.google.ipc.invalidation.ticl.android2.channel.AndroidChannelConstants.C2dmConstants;
25 import com.google.ipc.invalidation.ticl.proto.AndroidChannel.AddressedAndroidMessage;
26 import com.google.ipc.invalidation.util.ProtoWrapper.ValidationException;
27
28 import android.content.Context;
29 import android.content.Intent;
30 import android.util.Base64;
31
32
33 /**
34  * Service that receives messages from  using GCM.
35  *
36  */
37 public class AndroidMessageReceiverService extends MultiplexingGcmListener.AbstractListener {
38   /*
39    * This class is public so that it can be instantiated by the Android runtime. All of the
40    * {@code onYYY} methods are called holding a wakelock that will be automatically released when
41    * they return, since this is a subclass of {@code AbstractListener}.
42    */
43
44   /**
45    * Receiver for broadcasts by the multiplexed GCM service. It forwards them to
46    * AndroidMessageReceiverService.
47    */
48   public static class Receiver extends MultiplexingGcmListener.AbstractListener.Receiver {
49     /* This class is public so that it can be instantiated by the Android runtime. */
50     @Override
51     protected Class<?> getServiceClass() {
52       return AndroidMessageReceiverService.class;
53     }
54   }
55
56   private final Logger logger = AndroidLogger.forTag("MsgRcvrSvc");
57
58   public AndroidMessageReceiverService() {
59     super("AndroidMessageReceiverService");
60   }
61
62   @Override
63   protected void onMessage(Intent intent) {
64     // Forward the message to the Ticl service.
65     if (intent.hasExtra(C2dmConstants.CONTENT_PARAM)) {
66       String content = intent.getStringExtra(C2dmConstants.CONTENT_PARAM);
67       byte[] msgBytes = Base64.decode(content, Base64.URL_SAFE);
68       try {
69         // Look up the name of the Ticl service class from the manifest.
70         String serviceClass = new AndroidTiclManifest(this).getTiclServiceClass();
71         AddressedAndroidMessage addrMessage = AddressedAndroidMessage.parseFrom(msgBytes);
72         Intent msgIntent =
73             ProtocolIntents.InternalDowncalls.newServerMessageIntent(addrMessage.getMessage());
74         msgIntent.setClassName(this, serviceClass);
75         startService(msgIntent);
76       } catch (ValidationException exception) {
77         logger.warning("Failed parsing inbound message: %s", exception);
78       }
79     } else {
80       logger.fine("GCM Intent has no message content: %s", intent);
81     }
82
83     // Store the echo token.
84     String echoToken = intent.getStringExtra(C2dmConstants.ECHO_PARAM);
85     if (echoToken != null) {
86       AndroidChannelPreferences.setEchoToken(this, echoToken);
87     }
88   }
89
90   @Override
91   protected void onRegistered(String registrationId) {
92     // Inform the sender service that the registration id has changed. If the sender service
93     // had buffered a message because no registration id was previously available, this intent
94     // will cause it to send that message.
95     Intent sendBuffered = new Intent();
96     final String ignoredData = "";
97     sendBuffered.putExtra(AndroidChannelConstants.MESSAGE_SENDER_SVC_GCM_REGID_CHANGE, ignoredData);
98     sendBuffered.setClass(this, AndroidMessageSenderService.class);
99     startService(sendBuffered);
100
101     // Inform the Ticl service that the registration id has changed. This will cause it to send
102     // a message to the data center and update the GCM registration id stored at the data center.
103     Intent updateServer = ProtocolIntents.InternalDowncalls.newNetworkAddrChangeIntent();
104     updateServer.setClassName(this, new AndroidTiclManifest(this).getTiclServiceClass());
105     startService(updateServer);
106   }
107
108   @Override
109   protected void onUnregistered(String registrationId) {
110     // Nothing to do.
111   }
112
113   @Override
114   protected void onDeletedMessages(int total) {
115     // This method must be implemented if we start using non-collapsable messages with GCM. For
116     // now, there is nothing to do.
117   }
118
119   /**
120    * Initializes GCM as a convenience method for tests. In production, applications should handle
121    * this.
122    */
123   public static void initializeGcmForTest(Context context, Logger logger, String senderId) {
124     // Initialize GCM.
125     GCMRegistrar.checkDevice(context);
126     GCMRegistrar.checkManifest(context);
127     String regId = GCMRegistrar.getRegistrationId(context);
128     if (regId.isEmpty()) {
129       logger.info("Not registered with GCM; registering");
130       GCMRegistrar.register(context, senderId);
131     } else {
132       logger.fine("Already registered with GCM: %s", regId);
133     }
134   }
135 }