| /* |
| * 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.common; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.protobuf.ByteString; |
| import com.google.protos.ipc.invalidation.AndroidChannel; |
| import com.google.protos.ipc.invalidation.Channel.NetworkEndpointId; |
| import com.google.protos.ipc.invalidation.Channel.NetworkEndpointId.NetworkAddress; |
| import com.google.protos.ipc.invalidation.Client.AckHandleP; |
| import com.google.protos.ipc.invalidation.Client.PersistentStateBlob; |
| import com.google.protos.ipc.invalidation.Client.PersistentTiclState; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ApplicationClientIdP; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ClientVersion; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ConfigChangeMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ErrorMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.InfoRequestMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.InitializeMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.InitializeMessage.DigestSerializationType; |
| import com.google.protos.ipc.invalidation.ClientProtocol.InvalidationMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.InvalidationP; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ObjectIdP; |
| import com.google.protos.ipc.invalidation.ClientProtocol.PropertyRecord; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RateLimitP; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationP; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationStatus; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationStatusMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationSubtree; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationSummary; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationSyncMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.RegistrationSyncRequestMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ServerHeader; |
| import com.google.protos.ipc.invalidation.ClientProtocol.ServerToClientMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.StatusP; |
| import com.google.protos.ipc.invalidation.ClientProtocol.TokenControlMessage; |
| import com.google.protos.ipc.invalidation.ClientProtocol.Version; |
| |
| import java.util.List; |
| |
| |
| /** |
| * Utilities for creating protocol buffers. |
| * |
| */ |
| public class CommonProtos2 { |
| |
| |
| /** Returns true iff status corresponds to success. */ |
| public static boolean isSuccess(StatusP status) { |
| return status.getCode() == StatusP.Code.SUCCESS; |
| } |
| |
| /** Returns true iff status corresponds to transient failure. */ |
| public static boolean isTransientFailure(StatusP status) { |
| return status.getCode() == StatusP.Code.TRANSIENT_FAILURE; |
| } |
| |
| /** Returns true iff status corresponds to permanent failure. */ |
| public static boolean isPermanentFailure(StatusP status) { |
| return status.getCode() == StatusP.Code.PERMANENT_FAILURE; |
| } |
| |
| // The following methods help in creating a protobuf object given its components. A Nullable |
| // parameter implies that the particular field will not be set for that proto. |
| // For the specs, please see the corresponding Proto file (to avoid inconsistency due to |
| // duplication). |
| |
| public static Version newVersion(int majorVersion, int minorVersion) { |
| return Version.newBuilder().setMajorVersion(majorVersion).setMinorVersion(minorVersion).build(); |
| } |
| |
| public static ClientVersion newClientVersion(String platform, String language, |
| String applicationInfo) { |
| return ClientVersion.newBuilder() |
| .setVersion(CommonInvalidationConstants2.CLIENT_VERSION_VALUE) |
| .setPlatform(platform) |
| .setLanguage(language) |
| .setApplicationInfo(applicationInfo) |
| .build(); |
| } |
| |
| public static ObjectIdP newObjectIdP(int source, ByteString name) { |
| return ObjectIdP.newBuilder().setSource(source).setName(name).build(); |
| } |
| |
| public static ObjectIdP newObjectIdP(int source, byte[] name) { |
| return newObjectIdP(source, ByteString.copyFrom(name)); |
| } |
| |
| public static boolean isAllObjectId(ObjectIdP objectId) { |
| return (objectId != null) && |
| (CommonInvalidationConstants2.ALL_OBJECT_ID.getSource() == objectId.getSource()) && |
| (CommonInvalidationConstants2.ALL_OBJECT_ID.getName().equals(objectId.getName())); |
| |
| } |
| |
| public static RateLimitP newRateLimitP(int windowMs, int count) { |
| return RateLimitP.newBuilder() |
| .setWindowMs(windowMs) |
| .setCount(count) |
| .build(); |
| } |
| |
| public static ApplicationClientIdP newApplicationClientIdP(int clientType, |
| ByteString clientName) { |
| return ApplicationClientIdP.newBuilder() |
| .setClientType(clientType) |
| .setClientName(clientName) |
| .build(); |
| } |
| |
| public static InvalidationP newInvalidationP(ObjectIdP oid, long version) { |
| return newInvalidationP(oid, version, null, null, null); |
| } |
| |
| public static InvalidationP newInvalidationP(ObjectIdP oid, long version, |
| TrickleState trickleState) { |
| return newInvalidationP(oid, version, null, null, trickleState); |
| } |
| |
| public static InvalidationP newInvalidationP(ObjectIdP oid, long version, |
| ByteString payload, Long bridgeArrivalTimeMs) { |
| return newInvalidationP(oid, version, payload, bridgeArrivalTimeMs, null); |
| } |
| |
| public static InvalidationP newInvalidationP(ObjectIdP oid, long version, |
| ByteString payload, Long bridgeArrivalTimeMs, |
| TrickleState trickleState) { |
| InvalidationP.Builder builder = InvalidationP.newBuilder() |
| .setObjectId(oid) |
| .setIsKnownVersion(true) |
| .setVersion(version); |
| if (trickleState != null) { |
| builder.setIsTrickleRestart(trickleState == TrickleState.RESTART); |
| } |
| if (payload != null) { |
| builder.setPayload(payload); |
| } |
| if (bridgeArrivalTimeMs != null) { |
| builder.setBridgeArrivalTimeMs(bridgeArrivalTimeMs); |
| } |
| return builder.build(); |
| } |
| |
| public static InvalidationP newInvalidationPForUnknownVersion(ObjectIdP oid, long version) { |
| return InvalidationP.newBuilder() |
| .setObjectId(oid) |
| .setIsKnownVersion(false) |
| .setVersion(version) |
| .build(); |
| } |
| |
| public static RegistrationP newRegistrationP(ObjectIdP oid, boolean isReg) { |
| RegistrationP registration = RegistrationP.newBuilder() |
| .setObjectId(oid) |
| .setOpType(isReg ? RegistrationP.OpType.REGISTER : RegistrationP.OpType.UNREGISTER) |
| .build(); |
| return registration; |
| } |
| |
| public static StatusP newSuccessStatus() { |
| return StatusP.newBuilder().setCode(StatusP.Code.SUCCESS).build(); |
| } |
| |
| public static StatusP newFailureStatus(boolean isTransient, String description) { |
| return StatusP.newBuilder() |
| .setCode(isTransient ? StatusP.Code.TRANSIENT_FAILURE : StatusP.Code.PERMANENT_FAILURE) |
| .setDescription(description) |
| .build(); |
| } |
| |
| public static RegistrationSummary newRegistrationSummary(int numRegistrations, byte[] regDigest) { |
| RegistrationSummary regSummary = RegistrationSummary.newBuilder() |
| .setNumRegistrations(numRegistrations) |
| .setRegistrationDigest(ByteString.copyFrom(regDigest)) |
| .build(); |
| return regSummary; |
| } |
| |
| public static RegistrationStatus newRegistrationStatus(RegistrationP registration, |
| StatusP status) { |
| return RegistrationStatus.newBuilder() |
| .setRegistration(registration) |
| .setStatus(status) |
| .build(); |
| } |
| |
| public static RegistrationStatus newSuccessRegistrationStatus(RegistrationP registration) { |
| return RegistrationStatus.newBuilder() |
| .setRegistration(registration) |
| .setStatus(newSuccessStatus()) |
| .build(); |
| } |
| |
| public static PersistentTiclState newPersistentTiclState(ByteString clientToken, |
| long lastMessageSendTimeMs) { |
| return PersistentTiclState.newBuilder() |
| .setClientToken(clientToken) |
| .setLastMessageSendTimeMs(lastMessageSendTimeMs) |
| .build(); |
| } |
| |
| public static AckHandleP newAckHandleP(InvalidationP invalidation) { |
| return AckHandleP.newBuilder().setInvalidation(invalidation).build(); |
| } |
| |
| public static PersistentStateBlob newPersistentStateBlob(PersistentTiclState state, |
| ByteString mac) { |
| return PersistentStateBlob.newBuilder() |
| .setTiclState(state) |
| .setAuthenticationCode(mac) |
| .build(); |
| } |
| |
| // Methods to create ClientToServerMessages. |
| |
| public static InitializeMessage newInitializeMessage(int clientType, |
| ApplicationClientIdP applicationClientId, ByteString nonce, |
| DigestSerializationType digestSerializationType) { |
| return InitializeMessage.newBuilder() |
| .setClientType(clientType) |
| .setApplicationClientId(applicationClientId) |
| .setDigestSerializationType(digestSerializationType) |
| .setNonce(nonce) |
| .build(); |
| } |
| |
| public static PropertyRecord newPropertyRecord(String name, int value) { |
| return PropertyRecord.newBuilder().setName(name).setValue(value).build(); |
| } |
| |
| // Methods to create ServerToClientMessages. |
| |
| public static ServerHeader newServerHeader(ByteString clientToken, long currentTimeMs, |
| RegistrationSummary registrationSummary, String messageId) { |
| ServerHeader.Builder builder = ServerHeader.newBuilder() |
| .setProtocolVersion(CommonInvalidationConstants2.PROTOCOL_VERSION) |
| .setClientToken(clientToken) |
| .setServerTimeMs(currentTimeMs); |
| if (registrationSummary != null) { |
| builder.setRegistrationSummary(registrationSummary); |
| } |
| if (messageId != null) { |
| builder.setMessageId(messageId); |
| } |
| return builder.build(); |
| } |
| |
| public static ErrorMessage newErrorMessage(ErrorMessage.Code code, String description) { |
| return ErrorMessage.newBuilder() |
| .setCode(code) |
| .setDescription(description) |
| .build(); |
| } |
| |
| public static InvalidationMessage newInvalidationMessage(Iterable<InvalidationP> invalidations) { |
| return InvalidationMessage.newBuilder().addAllInvalidation(invalidations).build(); |
| } |
| |
| public static RegistrationSyncRequestMessage newRegistrationSyncRequestMessage() { |
| return RegistrationSyncRequestMessage.getDefaultInstance(); |
| } |
| |
| public static RegistrationSyncMessage newRegistrationSyncMessage( |
| List<RegistrationSubtree> subtrees) { |
| return RegistrationSyncMessage.newBuilder().addAllSubtree(subtrees).build(); |
| } |
| |
| public static RegistrationSubtree newRegistrationSubtree(List<ObjectIdP> registeredOids) { |
| return RegistrationSubtree.newBuilder().addAllRegisteredObject(registeredOids).build(); |
| } |
| |
| public static InfoRequestMessage newPerformanceCounterRequestMessage() { |
| return InfoRequestMessage.newBuilder() |
| .addInfoType(InfoRequestMessage.InfoType.GET_PERFORMANCE_COUNTERS) |
| .build(); |
| } |
| |
| public static ConfigChangeMessage newConfigChangeMessage(long nextMessageDelayMs) { |
| return ConfigChangeMessage.newBuilder().setNextMessageDelayMs(nextMessageDelayMs).build(); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .build(); |
| } |
| |
| public static ServerToClientMessage.Builder newServerToClientMessage(ServerHeader scHeader, |
| TokenControlMessage tokenControlMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setTokenControlMessage(tokenControlMessage); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader, |
| RegistrationSyncRequestMessage syncRequestionMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setRegistrationSyncRequestMessage(syncRequestionMessage) |
| .build(); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader, |
| InvalidationMessage invalidationMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setInvalidationMessage(invalidationMessage) |
| .build(); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader, |
| RegistrationStatusMessage registrationStatusMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setRegistrationStatusMessage(registrationStatusMessage) |
| .build(); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader, |
| InfoRequestMessage infoRequestMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setInfoRequestMessage(infoRequestMessage) |
| .build(); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader, |
| ConfigChangeMessage configChangeMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setConfigChangeMessage(configChangeMessage) |
| .build(); |
| } |
| |
| public static ServerToClientMessage newServerToClientMessage(ServerHeader scHeader, |
| ErrorMessage errorMessage) { |
| return ServerToClientMessage.newBuilder() |
| .setHeader(scHeader) |
| .setErrorMessage(errorMessage) |
| .build(); |
| } |
| |
| /** |
| * Constructs a network endpoint id for an Android client with the given {@code registrationId}, |
| * {@code clientKey}, and {@code packageName}. |
| */ |
| public static NetworkEndpointId newAndroidEndpointId(String registrationId, String clientKey, |
| String packageName, Version channelVersion) { |
| Preconditions.checkNotNull(registrationId, "Null registration id"); |
| Preconditions.checkNotNull(clientKey, "Null client key"); |
| Preconditions.checkNotNull(packageName, "Null package name"); |
| Preconditions.checkNotNull(channelVersion, "Null channel version"); |
| |
| AndroidChannel.EndpointId.Builder endpointBuilder = AndroidChannel.EndpointId.newBuilder() |
| .setC2DmRegistrationId(registrationId) |
| .setClientKey(clientKey) |
| .setPackageName(packageName); |
| |
| // The protocol version field was set in the INITIAL channel implementation but subsequent |
| // versions only set the channel version. |
| if (channelVersion == null) { |
| // TODO: Remove once unversioned clients are no longer supported |
| endpointBuilder.setProtocolVersion(CommonInvalidationConstants2.PROTOCOL_VERSION); |
| } else { |
| endpointBuilder.setChannelVersion(channelVersion); |
| } |
| return newNetworkEndpointId(NetworkAddress.ANDROID, endpointBuilder.build().toByteString()); |
| } |
| |
| public static NetworkEndpointId newNetworkEndpointId(NetworkAddress networkAddr, |
| ByteString clientAddr) { |
| return NetworkEndpointId.newBuilder() |
| .setNetworkAddress(networkAddr) |
| .setClientAddress(clientAddr) |
| .build(); |
| } |
| |
| private CommonProtos2() { // To prevent instantiation |
| } |
| } |