| Index: third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java
|
| diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d799ef62612a68023ea2fc0beffbc2035362bc5e
|
| --- /dev/null
|
| +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerIntents.java
|
| @@ -0,0 +1,220 @@
|
| +/*
|
| + * Copyright 2011 Google Inc.
|
| + *
|
| + * Licensed under the Apache License, Version 2.0 (the "License");
|
| + * you may not use this file except in compliance with the License.
|
| + * You may obtain a copy of the License at
|
| + *
|
| + * http://www.apache.org/licenses/LICENSE-2.0
|
| + *
|
| + * Unless required by applicable law or agreed to in writing, software
|
| + * distributed under the License is distributed on an "AS IS" BASIS,
|
| + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| + * See the License for the specific language governing permissions and
|
| + * limitations under the License.
|
| + */
|
| +package com.google.ipc.invalidation.external.client.contrib;
|
| +
|
| +import com.google.ipc.invalidation.external.client.SystemResources.Logger;
|
| +import com.google.ipc.invalidation.external.client.android.service.AndroidLogger;
|
| +import com.google.ipc.invalidation.external.client.contrib.AndroidListener.AlarmReceiver;
|
| +import com.google.ipc.invalidation.external.client.types.ObjectId;
|
| +import com.google.ipc.invalidation.ticl.android2.AndroidClock;
|
| +import com.google.ipc.invalidation.ticl.android2.AndroidTiclManifest;
|
| +import com.google.ipc.invalidation.ticl.android2.channel.AndroidChannelConstants.AuthTokenConstants;
|
| +import com.google.ipc.invalidation.ticl.proto.AndroidListenerProtocol.RegistrationCommand;
|
| +import com.google.ipc.invalidation.ticl.proto.AndroidListenerProtocol.StartCommand;
|
| +import com.google.ipc.invalidation.util.Bytes;
|
| +import com.google.ipc.invalidation.util.ProtoWrapper.ValidationException;
|
| +
|
| +import android.app.AlarmManager;
|
| +import android.app.PendingIntent;
|
| +import android.app.PendingIntent.CanceledException;
|
| +import android.content.Context;
|
| +import android.content.Intent;
|
| +
|
| +
|
| +/**
|
| + * Static helper class supporting construction and decoding of intents issued and handled by the
|
| + * {@link AndroidListener}.
|
| + *
|
| + */
|
| +class AndroidListenerIntents {
|
| +
|
| + /** The logger. */
|
| + private static final Logger logger = AndroidLogger.forPrefix("");
|
| +
|
| + /** Key of Intent byte[] holding a {@link RegistrationCommand} protocol buffer. */
|
| + static final String EXTRA_REGISTRATION =
|
| + "com.google.ipc.invalidation.android_listener.REGISTRATION";
|
| +
|
| + /** Key of Intent byte[] holding a {@link StartCommand} protocol buffer. */
|
| + static final String EXTRA_START =
|
| + "com.google.ipc.invalidation.android_listener.START";
|
| +
|
| + /** Key of Intent extra indicating that the client should stop. */
|
| + static final String EXTRA_STOP =
|
| + "com.google.ipc.invalidation.android_listener.STOP";
|
| +
|
| + /** Key of Intent extra holding a byte[] that is ack handle data. */
|
| + static final String EXTRA_ACK =
|
| + "com.google.ipc.invalidation.android_listener.ACK";
|
| +
|
| + /**
|
| + * Issues the given {@code intent} to the TICL service class registered in the {@code context}.
|
| + */
|
| + static void issueTiclIntent(Context context, Intent intent) {
|
| + context.startService(intent.setClassName(context,
|
| + new AndroidTiclManifest(context).getTiclServiceClass()));
|
| + }
|
| +
|
| + /**
|
| + * Issues the given {@code intent} to the {@link AndroidListener} class registered in the
|
| + * {@code context}.
|
| + */
|
| + static void issueAndroidListenerIntent(Context context, Intent intent) {
|
| + context.startService(setAndroidListenerClass(context, intent));
|
| + }
|
| +
|
| + /**
|
| + * Returns the ack handle from the given intent if it has the appropriate extra. Otherwise,
|
| + * returns {@code null}.
|
| + */
|
| + static byte[] findAckHandle(Intent intent) {
|
| + return intent.getByteArrayExtra(EXTRA_ACK);
|
| + }
|
| +
|
| + /**
|
| + * Returns {@link RegistrationCommand} extra from the given intent or null if no valid
|
| + * registration command exists.
|
| + */
|
| + static RegistrationCommand findRegistrationCommand(Intent intent) {
|
| + // Check that the extra exists.
|
| + byte[] data = intent.getByteArrayExtra(EXTRA_REGISTRATION);
|
| + if (null == data) {
|
| + return null;
|
| + }
|
| +
|
| + // Attempt to parse the extra.
|
| + try {
|
| + return RegistrationCommand.parseFrom(data);
|
| + } catch (ValidationException exception) {
|
| + logger.warning("Received invalid proto: %s", exception);
|
| + return null;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Returns {@link StartCommand} extra from the given intent or null if no valid start command
|
| + * exists.
|
| + */
|
| + static StartCommand findStartCommand(Intent intent) {
|
| + // Check that the extra exists.
|
| + byte[] data = intent.getByteArrayExtra(EXTRA_START);
|
| + if (null == data) {
|
| + return null;
|
| + }
|
| +
|
| + // Attempt to parse the extra.
|
| + try {
|
| + return StartCommand.parseFrom(data);
|
| + } catch (ValidationException exception) {
|
| + logger.warning("Received invalid proto: %s", exception);
|
| + return null;
|
| + }
|
| + }
|
| +
|
| + /** Returns {@code true} if the intent has the 'stop' extra. */
|
| + static boolean isStopIntent(Intent intent) {
|
| + return intent.hasExtra(EXTRA_STOP);
|
| + }
|
| +
|
| + /** Issues a registration retry with delay. */
|
| + static void issueDelayedRegistrationIntent(Context context, AndroidClock clock,
|
| + Bytes clientId, ObjectId objectId, boolean isRegister, int delayMs, int requestCode) {
|
| + RegistrationCommand command = isRegister ?
|
| + AndroidListenerProtos.newDelayedRegisterCommand(clientId, objectId) :
|
| + AndroidListenerProtos.newDelayedUnregisterCommand(clientId, objectId);
|
| + Intent intent = new Intent()
|
| + .putExtra(EXTRA_REGISTRATION, command.toByteArray())
|
| + .setClass(context, AlarmReceiver.class);
|
| +
|
| + // Create a pending intent that will cause the AlarmManager to fire the above intent.
|
| + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent,
|
| + PendingIntent.FLAG_ONE_SHOT);
|
| +
|
| + // Schedule the pending intent after the appropriate delay.
|
| + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
| + long executeMs = clock.nowMs() + delayMs;
|
| + alarmManager.set(AlarmManager.RTC, executeMs, pendingIntent);
|
| + }
|
| +
|
| + /** Creates a 'start-client' intent. */
|
| + static Intent createStartIntent(Context context, int clientType, Bytes clientName,
|
| + boolean allowSuppression) {
|
| + Intent intent = new Intent();
|
| + // Create proto for the start command.
|
| + StartCommand command =
|
| + AndroidListenerProtos.newStartCommand(clientType, clientName, allowSuppression);
|
| + intent.putExtra(EXTRA_START, command.toByteArray());
|
| + return setAndroidListenerClass(context, intent);
|
| + }
|
| +
|
| + /** Creates a 'stop-client' intent. */
|
| + static Intent createStopIntent(Context context) {
|
| + // Stop command just has the extra (its content doesn't matter).
|
| + Intent intent = new Intent();
|
| + intent.putExtra(EXTRA_STOP, true);
|
| + return setAndroidListenerClass(context, intent);
|
| + }
|
| +
|
| + /** Create an ack intent. */
|
| + static Intent createAckIntent(Context context, byte[] ackHandle) {
|
| + // Ack intent has an extra containing the ack handle data.
|
| + Intent intent = new Intent();
|
| + intent.putExtra(EXTRA_ACK, ackHandle);
|
| + return setAndroidListenerClass(context, intent);
|
| + }
|
| +
|
| + /** Constructs an intent with {@link RegistrationCommand} proto. */
|
| + static Intent createRegistrationIntent(Context context, Bytes clientId,
|
| + Iterable<ObjectId> objectIds, boolean isRegister) {
|
| + // Registration intent has an extra containing the RegistrationCommand proto.
|
| + Intent intent = new Intent();
|
| + RegistrationCommand command =
|
| + AndroidListenerProtos.newRegistrationCommand(clientId, objectIds, isRegister);
|
| + intent.putExtra(EXTRA_REGISTRATION, command.toByteArray());
|
| + return setAndroidListenerClass(context, intent);
|
| + }
|
| +
|
| + /** Sets the appropriate class for {@link AndroidListener} service intents. */
|
| + static Intent setAndroidListenerClass(Context context, Intent intent) {
|
| + String simpleListenerClass = new AndroidTiclManifest(context).getListenerServiceClass();
|
| + return intent.setClassName(context, simpleListenerClass);
|
| + }
|
| +
|
| + /** Returns {@code true} iff the given intent is an authorization token request. */
|
| + static boolean isAuthTokenRequest(Intent intent) {
|
| + return AuthTokenConstants.ACTION_REQUEST_AUTH_TOKEN.equals(intent.getAction());
|
| + }
|
| +
|
| + /**
|
| + * Given an authorization token request intent and authorization information ({@code authToken}
|
| + * and {@code authType}) issues a response.
|
| + */
|
| + static void issueAuthTokenResponse(Context context, PendingIntent pendingIntent, String authToken,
|
| + String authType) {
|
| + Intent responseIntent = new Intent()
|
| + .putExtra(AuthTokenConstants.EXTRA_AUTH_TOKEN, authToken)
|
| + .putExtra(AuthTokenConstants.EXTRA_AUTH_TOKEN_TYPE, authType);
|
| + try {
|
| + pendingIntent.send(context, 0, responseIntent);
|
| + } catch (CanceledException exception) {
|
| + logger.warning("Canceled auth request: %s", exception);
|
| + }
|
| + }
|
| +
|
| + // Prevent instantiation.
|
| + private AndroidListenerIntents() {
|
| + }
|
| +}
|
|
|