Added Android code
[wl-app.git] / iOS / Pods / FirebaseMessaging / Firebase / Messaging / FIRMessagingSyncMessageManager.m
1 /*
2  * Copyright 2017 Google
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
17 #import "FIRMessagingSyncMessageManager.h"
18
19 #import "FIRMessagingConstants.h"
20 #import "FIRMessagingDefines.h"
21 #import "FIRMessagingLogger.h"
22 #import "FIRMessagingPersistentSyncMessage.h"
23 #import "FIRMessagingRmqManager.h"
24 #import "FIRMessagingUtilities.h"
25
26 static const int64_t kDefaultSyncMessageTTL = 4 * 7 * 24 * 60 * 60;  // 4 weeks
27 // 4 MB of free space is required to persist Sync messages
28 static const uint64_t kMinFreeDiskSpaceInMB = 1;
29
30 @interface FIRMessagingSyncMessageManager()
31
32 @property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmqManager;
33
34 @end
35
36 @implementation FIRMessagingSyncMessageManager
37
38 - (instancetype)init {
39   FIRMessagingInvalidateInitializer();
40 }
41
42 - (instancetype)initWithRmqManager:(FIRMessagingRmqManager *)rmqManager {
43   _FIRMessagingDevAssert(rmqManager, @"Invalid nil rmq manager while initalizing sync message manager");
44   self = [super init];
45   if (self) {
46     _rmqManager = rmqManager;
47   }
48   return self;
49 }
50
51 - (void)removeExpiredSyncMessages {
52   NSError *error;
53   int deleteCount = [self.rmqManager deleteExpiredOrFinishedSyncMessages:&error];
54   if (error) {
55     FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager000,
56                             @"Error while deleting expired sync messages %@", error);
57   } else if (deleteCount > 0) {
58     FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSyncMessageManager001,
59                             @"Successfully deleted %d sync messages from store", deleteCount);
60   }
61 }
62
63 - (BOOL)didReceiveAPNSSyncMessage:(NSDictionary *)message {
64   return [self didReceiveSyncMessage:message viaAPNS:YES viaMCS:NO];
65 }
66
67 - (BOOL)didReceiveMCSSyncMessage:(NSDictionary *)message {
68   return [self didReceiveSyncMessage:message viaAPNS:NO viaMCS:YES];
69 }
70
71 - (BOOL)didReceiveSyncMessage:(NSDictionary *)message
72                       viaAPNS:(BOOL)viaAPNS
73                        viaMCS:(BOOL)viaMCS {
74   NSString *rmqID = message[kFIRMessagingMessageIDKey];
75   _FIRMessagingDevAssert([rmqID length], @"Invalid nil rmqID for message");
76   if (![rmqID length]) {
77     FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager002,
78                             @"Invalid nil rmqID for sync message.");
79     return NO;
80   }
81
82   FIRMessagingPersistentSyncMessage *persistentMessage =
83       [self.rmqManager querySyncMessageWithRmqID:rmqID];
84
85   NSError *error;
86   if (!persistentMessage) {
87
88     // Do not persist the new message if we don't have enough disk space
89     uint64_t freeDiskSpace = FIRMessagingGetFreeDiskSpaceInMB();
90     if (freeDiskSpace < kMinFreeDiskSpaceInMB) {
91       return NO;
92     }
93
94     int64_t expirationTime = [[self class] expirationTimeForSyncMessage:message];
95     if (![self.rmqManager saveSyncMessageWithRmqID:rmqID
96                                     expirationTime:expirationTime
97                                       apnsReceived:viaAPNS
98                                        mcsReceived:viaMCS
99                                              error:&error]) {
100       FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager003,
101                               @"Failed to save sync message with rmqID %@", rmqID);
102     } else {
103       FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager004,
104                              @"Added sync message to cache: %@", rmqID);
105     }
106     return NO;
107   }
108
109   if (viaAPNS && !persistentMessage.apnsReceived) {
110     persistentMessage.apnsReceived = YES;
111     if (![self.rmqManager updateSyncMessageViaAPNSWithRmqID:rmqID error:&error]) {
112       FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager005,
113                               @"Failed to update APNS state for sync message %@", rmqID);
114     }
115   } else if (viaMCS && !persistentMessage.mcsReceived) {
116     persistentMessage.mcsReceived = YES;
117     if (![self.rmqManager updateSyncMessageViaMCSWithRmqID:rmqID error:&error]) {
118       FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager006,
119                               @"Failed to update MCS state for sync message %@", rmqID);
120     }
121   }
122
123   // Received message via both ways we can safely delete it.
124   if (persistentMessage.apnsReceived && persistentMessage.mcsReceived) {
125     if (![self.rmqManager deleteSyncMessageWithRmqID:rmqID]) {
126       FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager007,
127                               @"Failed to delete sync message %@", rmqID);
128     } else {
129       FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager008,
130                              @"Successfully deleted sync message from cache %@", rmqID);
131     }
132   }
133
134   // Already received this message either via MCS or APNS.
135   return YES;
136 }
137
138 + (int64_t)expirationTimeForSyncMessage:(NSDictionary *)message {
139   int64_t ttl = kDefaultSyncMessageTTL;
140   if (message[kFIRMessagingMessageSyncMessageTTLKey]) {
141     ttl = [message[kFIRMessagingMessageSyncMessageTTLKey] longLongValue];
142   }
143   int64_t currentTime = FIRMessagingCurrentTimestampInSeconds();
144   return currentTime + ttl;
145 }
146
147 @end