diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-08-31 23:07:20 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-08-31 23:07:20 +0200 |
| commit | 22721a013bdd10d5eb395ba18453585f5f3f1f7f (patch) | |
| tree | 5a920e31d6026ed5dc55265e5fd057febccc50e3 /StoneIsland/platforms/ios/Pods/FirebaseMessaging | |
| parent | d22d51a1ae49680015326857360eb699f31efced (diff) | |
rebuild the ios platform and the plugins
Diffstat (limited to 'StoneIsland/platforms/ios/Pods/FirebaseMessaging')
92 files changed, 18613 insertions, 0 deletions
diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRAppInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRAppInternal.h new file mode 100644 index 00000000..9a0c943d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRAppInternal.h @@ -0,0 +1,173 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#if SWIFT_PACKAGE +// TODO(paulb777): Investigate if there's a common strategy for both Cocoapods and Swift PM. +#import "FIRApp.h" +#else +#import <FirebaseCore/FIRApp.h> +#endif + +// The has_include is a workaround so the old IID needed for the FIS tests can find FIRErrors.h +#if __has_include("FirebaseCore/Sources/Private/FIRErrors.h") +#import "FirebaseCore/Sources/Private/FIRErrors.h" +#else +#import <FirebaseCore/FIRErrors.h> +#endif + +@class FIRComponentContainer; +@protocol FIRLibrary; + +/** + * The internal interface to FIRApp. This is meant for first-party integrators, who need to receive + * FIRApp notifications, log info about the success or failure of their configuration, and access + * other internal functionality of FIRApp. + * + * TODO(b/28296561): Restructure this header. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; + +/** + * The format string for the User Defaults key used for storing the data collection enabled flag. + * This includes formatting to append the Firebase App's name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** + * A notification fired containing diagnostic information when SDK errors occur. + */ +extern NSString *const kFIRAppDiagnosticsNotification; + +/** @var FIRAuthStateDidChangeInternalNotification + @brief The name of the @c NSNotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FIRAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FIRAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FIRAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FIRApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FIRAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/* + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * Creates an error for failing to configure a subspec service. This method is called by each + * FIRApp notification listener. + */ ++ (NSError *)errorForSubspecConfigurationFailureWithDomain:(NSString *)domain + errorCode:(FIRErrorCode)code + service:(NSString *)service + reason:(NSString *)reason; +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Used by each SDK to send logs about SDK configuration status to Clearcut. + * + * @note This API is a no-op, please remove calls to it. + */ +- (void)sendLogsWithServiceName:(NSString *)serviceName + version:(NSString *)version + error:(NSError *)error; + +/** + * Can be used by the unit tests in eack SDK to reset FIRApp. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponent.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponent.h new file mode 100644 index 00000000..cb51ee70 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the Component. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray<FIRDependency *> *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray<FIRDependency *> *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponentContainer.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponentContainer.h new file mode 100644 index 00000000..db2bafef --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponentContainer.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Google + * + * 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. + */ +#import <Foundation/Foundation.h> + +// The has_include is a workaround so the old IID needed for the FIS tests can find the headers. +#if __has_include("FirebaseCore/Sources/Private/FIRComponentType.h") +#import "FirebaseCore/Sources/Private/FIRComponentType.h" +#import "FirebaseCore/Sources/Private/FIRLibrary.h" +#else +#import <FirebaseCore/FIRComponentType.h> +#import <FirebaseCore/FIRLibrary.h> +#endif + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType<id<type>> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant:` call. These classes should conform to `FIRComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +/// Unavailable. Use the `container` property on `FIRApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponentType.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponentType.h new file mode 100644 index 00000000..6f2aca7b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRComponentType.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (T)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h new file mode 100644 index 00000000..76c0c05f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h @@ -0,0 +1,35 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class FIRDiagnosticsData; +@class FIROptions; + +NS_ASSUME_NONNULL_BEGIN + +/** Connects FIRCore with the CoreDiagnostics library. */ +@interface FIRCoreDiagnosticsConnector : NSObject + +/** Logs FirebaseCore related data. + * + * @param options The options object containing data to log. + */ ++ (void)logCoreTelemetryWithOptions:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRDependency.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRDependency.h new file mode 100644 index 00000000..46e9b7ea --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `dependencyWithProtocol:isRequired:` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRErrorCode.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRErrorCode.h new file mode 100644 index 00000000..c90d9eec --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRErrorCode.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +/** Error codes in Firebase error domain. */ +typedef NS_ENUM(NSInteger, FIRErrorCode) { + /** + * Unknown error. + */ + FIRErrorCodeUnknown = 0, + /** + * Loading data from the GoogleService-Info.plist file failed. This is a fatal error and should + * not be ignored. Further calls to the API will fail and/or possibly cause crashes. + */ + FIRErrorCodeInvalidPlistFile = -100, + + /** + * Validating the Google App ID format failed. + */ + FIRErrorCodeInvalidAppID = -101, + + /** + * Error code for failing to configure a specific service. It's deprecated, but + * still used after copybara. + */ + FIRErrorCodeConfigFailed = -114, +}; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRErrors.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRErrors.h new file mode 100644 index 00000000..19e47328 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRErrors.h @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#include "FIRErrorCode.h" + +extern NSString *const kFirebaseErrorDomain; +extern NSString *const kFirebaseConfigErrorDomain; +extern NSString *const kFirebaseCoreErrorDomain; +extern NSString *const kFirebasePerfErrorDomain; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h new file mode 100644 index 00000000..bfff73e5 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h @@ -0,0 +1,39 @@ +// Copyright 2019 Google +// +// 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. + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRHeartbeatInfo : NSObject + +// Enum representing the different heartbeat codes. +typedef NS_ENUM(NSInteger, FIRHeartbeatInfoCode) { + FIRHeartbeatInfoCodeNone = 0, + FIRHeartbeatInfoCodeSDK = 1, + FIRHeartbeatInfoCodeGlobal = 2, + FIRHeartbeatInfoCodeCombined = 3, +}; + +/** + * Get heartbeat code requred for the sdk. + * @param heartbeatTag String representing the sdk heartbeat tag. + * @return Heartbeat code indicating whether or not an sdk/global heartbeat + * needs to be sent + */ ++ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRLibrary.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRLibrary.h new file mode 100644 index 00000000..e7a9e077 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRLibrary.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import <Foundation/Foundation.h> + +// The has_include is a workaround so the old IID needed for the FIS tests can find the headers. +#if __has_include("FirebaseCore/Sources/Private/FIRComponent.h") +#import "FirebaseCore/Sources/Private/FIRComponent.h" +#else +#import <FirebaseCore/FIRComponent.h> +#endif + +@class FIRApp; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more FIRComponents that will be registered in +/// FIRApp and participate in dependency resolution and injection. ++ (NSArray<FIRComponent *> *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRLogger.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRLogger.h new file mode 100644 index 00000000..6fd77844 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIRLogger.h @@ -0,0 +1,156 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#if SWIFT_PACKAGE +// TODO(paulb777): Investigate if there's a common strategy for both Cocoapods and Swift PM. +#import "FIRLoggerLevel.h" +#else +#import <FirebaseCore/FIRLoggerLevel.h> +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerABTesting; +extern FIRLoggerService kFIRLoggerAdMob; +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerAuth; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerMLKit; +extern FIRLoggerService kFIRLoggerPerf; +extern FIRLoggerService kFIRLoggerRemoteConfig; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to YES, the logging level for Analytics will be set to FIRLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Changes the default logging level of FIRLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FIRLoggerLevelNotice if the app is running from App Store. + * (required) log level (one of the FIRLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * Logs a message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FIRLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) service name of type FIRLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + */ +extern void FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + NSString *messageCode, + NSString *message, +// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable +// See: http://stackoverflow.com/q/29095469 +#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX + va_list args_ptr +#else + va_list _Nullable args_ptr +#endif +); + +/** + * The following functions accept the following parameters in order: + * (required) service name of type FIRLoggerService. + * (required) message code starting from "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * See go/firebase-log-proposal for details. + * (required) message string which can be a format string. + * (optional) the list of arguments to substitute into the format string. + * Example usage: + * FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +@interface FIRLoggerWrapper : NSObject + +/** + * Objective-C wrapper for FIRLogBasic to allow weak linking to FIRLogger + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) service name of type FIRLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + */ + ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIROptionsInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIROptionsInternal.h new file mode 100644 index 00000000..acaf4586 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FIROptionsInternal.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#if SWIFT_PACKAGE +// TODO(paulb777): Investigate if there's a common strategy for both Cocoapods and Swift PM. +#import "FIROptions.h" +#else +#import <FirebaseCore/FIROptions.h> +#endif + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FIROptions to internal use. + */ +@interface FIROptions () + +/** + * resetDefaultOptions and initInternalWithOptionsDictionary: are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary; + +/** + * defaultOptions and defaultOptionsDictionary are exposed in order to be used in FIRApp and + * other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If YES, then + * isAnalyticsCollectionEnabled will be NO. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not Analytics was enabled in the developer console. + */ +@property(nonatomic, readonly) BOOL isAnalyticsEnabled; + +/** + * Whether or not SignIn was enabled in the developer console. + */ +@property(nonatomic, readonly) BOOL isSignInEnabled; + +/** + * Whether or not editing is locked. This should occur after FIROptions has been set on a FIRApp. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FirebaseCoreInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FirebaseCoreInternal.h new file mode 100644 index 00000000..93af6cb8 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseCore/Sources/Private/FirebaseCoreInternal.h @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC +// +// 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. + +// An umbrella header, for any other libraries in this repo to access Firebase Public and Private +// headers. Any package manager complexity should be handled here. + +#if SWIFT_PACKAGE +@import FirebaseCore; +#else +#import <FirebaseCore/FirebaseCore.h> +#endif + +#import "FirebaseCore/Sources/Private/FIRAppInternal.h" +#import "FirebaseCore/Sources/Private/FIRComponent.h" +#import "FirebaseCore/Sources/Private/FIRComponentContainer.h" +#import "FirebaseCore/Sources/Private/FIRDependency.h" +#import "FirebaseCore/Sources/Private/FIRHeartbeatInfo.h" +#import "FirebaseCore/Sources/Private/FIRLibrary.h" +#import "FirebaseCore/Sources/Private/FIRLogger.h" +#import "FirebaseCore/Sources/Private/FIROptionsInternal.h" diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h new file mode 100644 index 00000000..cd40f172 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC +// +// 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. + +// An umbrella header, for any other libraries in this repo to access Firebase +// Installations Public headers. Any package manager complexity should be +// handled here. + +#if SWIFT_PACKAGE +@import FirebaseInstallations; +#else +#import <FirebaseInstallations/FirebaseInstallations.h> +#endif diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMMessageCode.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMMessageCode.h new file mode 100644 index 00000000..a9777ed9 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMMessageCode.h @@ -0,0 +1,209 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) { + // FIRMessaging+FIRApp.m + kFIRMessagingMessageCodeFIRApp000 = 1000, // I-FCM001000 + kFIRMessagingMessageCodeFIRApp001 = 1001, // I-FCM001001 + // FIRMessaging.m + kFIRMessagingMessageCodeMessagingPrintLibraryVersion = 2000, // I-FCM002000 + kFIRMessagingMessageCodeMessaging001 = 2001, // I-FCM002001 + kFIRMessagingMessageCodeMessaging002 = 2002, // I-FCM002002 - no longer used + kFIRMessagingMessageCodeMessaging003 = 2003, // I-FCM002003 + kFIRMessagingMessageCodeMessaging004 = 2004, // I-FCM002004 + kFIRMessagingMessageCodeMessaging005 = 2005, // I-FCM002005 + kFIRMessagingMessageCodeMessaging006 = 2006, // I-FCM002006 - no longer used + kFIRMessagingMessageCodeMessaging007 = 2007, // I-FCM002007 - no longer used + kFIRMessagingMessageCodeMessaging008 = 2008, // I-FCM002008 - no longer used + kFIRMessagingMessageCodeMessaging009 = 2009, // I-FCM002009 + kFIRMessagingMessageCodeMessaging010 = 2010, // I-FCM002010 + kFIRMessagingMessageCodeMessaging011 = 2011, // I-FCM002011 + kFIRMessagingMessageCodeMessaging012 = 2012, // I-FCM002012 + kFIRMessagingMessageCodeMessaging013 = 2013, // I-FCM002013 + kFIRMessagingMessageCodeMessaging014 = 2014, // I-FCM002014 + kFIRMessagingMessageCodeMessaging015 = 2015, // I-FCM002015 + kFIRMessagingMessageCodeMessaging016 = 2016, // I-FCM002016 - no longer used + kFIRMessagingMessageCodeMessaging017 = 2017, // I-FCM002017 + kFIRMessagingMessageCodeMessaging018 = 2018, // I-FCM002018 + kFIRMessagingMessageCodeRemoteMessageDelegateMethodNotImplemented = 2019, // I-FCM002019 + kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch = 2020, // I-FCM002020 + kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete = 2021, // I-FCM002021 + kFIRMessagingMessageCodeAPNSTokenNotAvailableDuringTokenFetch = 2022, // I-FCM002022 + kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented = 2023, // I-FCM002023 + kFIRMessagingMessageCodeTopicFormatIsDeprecated = 2024, + kFIRMessagingMessageCodeDirectChannelConnectionFailed = 2025, + kFIRMessagingMessageCodeInvalidClient = 2026, + // FIRMessagingClient.m + kFIRMessagingMessageCodeClient000 = 4000, // I-FCM004000 + kFIRMessagingMessageCodeClient001 = 4001, // I-FCM004001 + kFIRMessagingMessageCodeClient002 = 4002, // I-FCM004002 + kFIRMessagingMessageCodeClient003 = 4003, // I-FCM004003 + kFIRMessagingMessageCodeClient004 = 4004, // I-FCM004004 + kFIRMessagingMessageCodeClient005 = 4005, // I-FCM004005 + kFIRMessagingMessageCodeClient006 = 4006, // I-FCM004006 + kFIRMessagingMessageCodeClient007 = 4007, // I-FCM004007 + kFIRMessagingMessageCodeClient008 = 4008, // I-FCM004008 + kFIRMessagingMessageCodeClient009 = 4009, // I-FCM004009 + kFIRMessagingMessageCodeClient010 = 4010, // I-FCM004010 + kFIRMessagingMessageCodeClient011 = 4011, // I-FCM004011 + kFIRMessagingMessageCodeClientInvalidState = 4012, + kFIRMessagingMessageCodeClientInvalidStateTimeout = 4013, + + // FIRMessagingConnection.m + kFIRMessagingMessageCodeConnection000 = 5000, // I-FCM005000 + kFIRMessagingMessageCodeConnection001 = 5001, // I-FCM005001 + kFIRMessagingMessageCodeConnection002 = 5002, // I-FCM005002 + kFIRMessagingMessageCodeConnection003 = 5003, // I-FCM005003 + kFIRMessagingMessageCodeConnection004 = 5004, // I-FCM005004 + kFIRMessagingMessageCodeConnection005 = 5005, // I-FCM005005 + kFIRMessagingMessageCodeConnection006 = 5006, // I-FCM005006 + kFIRMessagingMessageCodeConnection007 = 5007, // I-FCM005007 + kFIRMessagingMessageCodeConnection008 = 5008, // I-FCM005008 + kFIRMessagingMessageCodeConnection009 = 5009, // I-FCM005009 + kFIRMessagingMessageCodeConnection010 = 5010, // I-FCM005010 + kFIRMessagingMessageCodeConnection011 = 5011, // I-FCM005011 + kFIRMessagingMessageCodeConnection012 = 5012, // I-FCM005012 + kFIRMessagingMessageCodeConnection013 = 5013, // I-FCM005013 + kFIRMessagingMessageCodeConnection014 = 5014, // I-FCM005014 + kFIRMessagingMessageCodeConnection015 = 5015, // I-FCM005015 + kFIRMessagingMessageCodeConnection016 = 5016, // I-FCM005016 + kFIRMessagingMessageCodeConnection017 = 5017, // I-FCM005017 + kFIRMessagingMessageCodeConnection018 = 5018, // I-FCM005018 + kFIRMessagingMessageCodeConnection019 = 5019, // I-FCM005019 + kFIRMessagingMessageCodeConnection020 = 5020, // I-FCM005020 + kFIRMessagingMessageCodeConnection021 = 5021, // I-FCM005021 + kFIRMessagingMessageCodeConnection022 = 5022, // I-FCM005022 + kFIRMessagingMessageCodeConnection023 = 5023, // I-FCM005023 + // FIRMessagingContextManagerService.m + kFIRMessagingMessageCodeContextManagerService000 = 6000, // I-FCM006000 + kFIRMessagingMessageCodeContextManagerService001 = 6001, // I-FCM006001 + kFIRMessagingMessageCodeContextManagerService002 = 6002, // I-FCM006002 + kFIRMessagingMessageCodeContextManagerService003 = 6003, // I-FCM006003 + kFIRMessagingMessageCodeContextManagerService004 = 6004, // I-FCM006004 + kFIRMessagingMessageCodeContextManagerService005 = 6005, // I-FCM006005 + kFIRMessagingMessageCodeContextManagerServiceFailedLocalSchedule = 6006, // I-FCM006006 + // FIRMessagingDataMessageManager.m + // DO NOT USE 7005 + kFIRMessagingMessageCodeDataMessageManager000 = 7000, // I-FCM007000 + kFIRMessagingMessageCodeDataMessageManager001 = 7001, // I-FCM007001 + kFIRMessagingMessageCodeDataMessageManager002 = 7002, // I-FCM007002 + kFIRMessagingMessageCodeDataMessageManager003 = 7003, // I-FCM007003 + kFIRMessagingMessageCodeDataMessageManager004 = 7004, // I-FCM007004 + kFIRMessagingMessageCodeDataMessageManager006 = 7006, // I-FCM007006 + kFIRMessagingMessageCodeDataMessageManager007 = 7007, // I-FCM007007 + kFIRMessagingMessageCodeDataMessageManager008 = 7008, // I-FCM007008 + kFIRMessagingMessageCodeDataMessageManager009 = 7009, // I-FCM007009 + kFIRMessagingMessageCodeDataMessageManager010 = 7010, // I-FCM007010 + kFIRMessagingMessageCodeDataMessageManager011 = 7011, // I-FCM007011 + kFIRMessagingMessageCodeDataMessageManager012 = 7012, // I-FCM007012 + kFIRMessagingMessageCodeDataMessageManager013 = 7013, + + // FIRMessagingPendingTopicsList.m + kFIRMessagingMessageCodePendingTopicsList000 = 8000, // I-FCM008000 + // FIRMessagingPubSub.m + kFIRMessagingMessageCodePubSub000 = 9000, // I-FCM009000 + kFIRMessagingMessageCodePubSub001 = 9001, // I-FCM009001 + kFIRMessagingMessageCodePubSub002 = 9002, // I-FCM009002 + kFIRMessagingMessageCodePubSub003 = 9003, // I-FCM009003 + kFIRMessagingMessageCodePubSubArchiveError = 9004, + kFIRMessagingMessageCodePubSubUnarchiveError = 9005, + + // FIRMessagingReceiver.m + kFIRMessagingMessageCodeReceiver000 = 10000, // I-FCM010000 + kFIRMessagingMessageCodeReceiver001 = 10001, // I-FCM010001 + kFIRMessagingMessageCodeReceiver002 = 10002, // I-FCM010002 + kFIRMessagingMessageCodeReceiver003 = 10003, // I-FCM010003 + kFIRMessagingMessageCodeReceiver004 = 10004, // I-FCM010004 - no longer used + kFIRMessagingMessageCodeReceiver005 = 10005, // I-FCM010005 + // FIRMessagingRegistrar.m + kFIRMessagingMessageCodeRegistrar000 = 11000, // I-FCM011000 + // FIRMessagingRemoteNotificationsProxy.m + kFIRMessagingMessageCodeRemoteNotificationsProxy000 = 12000, // I-FCM012000 + kFIRMessagingMessageCodeRemoteNotificationsProxy001 = 12001, // I-FCM012001 + kFIRMessagingMessageCodeRemoteNotificationsProxyAPNSFailed = 12002, // I-FCM012002 + kFIRMessagingMessageCodeRemoteNotificationsProxyMethodNotAdded = 12003, // I-FCM012003 + // FIRMessagingRmq2PersistentStore.m + // DO NOT USE 13000, 13001, 13009 + kFIRMessagingMessageCodeRmq2PersistentStore002 = 13002, // I-FCM013002 + kFIRMessagingMessageCodeRmq2PersistentStore003 = 13003, // I-FCM013003 + kFIRMessagingMessageCodeRmq2PersistentStore004 = 13004, // I-FCM013004 + kFIRMessagingMessageCodeRmq2PersistentStore005 = 13005, // I-FCM013005 + kFIRMessagingMessageCodeRmq2PersistentStore006 = 13006, // I-FCM013006 + kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase = 13007, // I-FCM013007 + kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase = 13008, // I-FCM013008 + kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingTable = 13010, // I-FCM013010 + // FIRMessagingRmqManager.m + kFIRMessagingMessageCodeRmqManager000 = 14000, // I-FCM014000 + // FIRMessagingSecureSocket.m + kFIRMessagingMessageCodeSecureSocket000 = 15000, // I-FCM015000 + kFIRMessagingMessageCodeSecureSocket001 = 15001, // I-FCM015001 + kFIRMessagingMessageCodeSecureSocket002 = 15002, // I-FCM015002 + kFIRMessagingMessageCodeSecureSocket003 = 15003, // I-FCM015003 + kFIRMessagingMessageCodeSecureSocket004 = 15004, // I-FCM015004 + kFIRMessagingMessageCodeSecureSocket005 = 15005, // I-FCM015005 + kFIRMessagingMessageCodeSecureSocket006 = 15006, // I-FCM015006 + kFIRMessagingMessageCodeSecureSocket007 = 15007, // I-FCM015007 + kFIRMessagingMessageCodeSecureSocket008 = 15008, // I-FCM015008 + kFIRMessagingMessageCodeSecureSocket009 = 15009, // I-FCM015009 + kFIRMessagingMessageCodeSecureSocket010 = 15010, // I-FCM015010 + kFIRMessagingMessageCodeSecureSocket011 = 15011, // I-FCM015011 + kFIRMessagingMessageCodeSecureSocket012 = 15012, // I-FCM015012 + kFIRMessagingMessageCodeSecureSocket013 = 15013, // I-FCM015013 + kFIRMessagingMessageCodeSecureSocket014 = 15014, // I-FCM015014 + kFIRMessagingMessageCodeSecureSocket015 = 15015, // I-FCM015015 + kFIRMessagingMessageCodeSecureSocket016 = 15016, // I-FCM015016 + // FIRMessagingSyncMessageManager.m + // DO NOT USE 16000, 16003 + kFIRMessagingMessageCodeSyncMessageManager001 = 16001, // I-FCM016001 + kFIRMessagingMessageCodeSyncMessageManager002 = 16002, // I-FCM016002 + kFIRMessagingMessageCodeSyncMessageManager004 = 16004, // I-FCM016004 + kFIRMessagingMessageCodeSyncMessageManager005 = 16005, // I-FCM016005 + kFIRMessagingMessageCodeSyncMessageManager006 = 16006, // I-FCM016006 + kFIRMessagingMessageCodeSyncMessageManager007 = 16007, // I-FCM016007 + kFIRMessagingMessageCodeSyncMessageManager008 = 16008, // I-FCM016008 + // FIRMessagingTopicOperation.m + kFIRMessagingMessageCodeTopicOption000 = 17000, // I-FCM017000 + kFIRMessagingMessageCodeTopicOption001 = 17001, // I-FCM017001 + kFIRMessagingMessageCodeTopicOption002 = 17002, // I-FCM017002 + kFIRMessagingMessageCodeTopicOptionTopicEncodingFailed = 17003, // I-FCM017003 + kFIRMessagingMessageCodeTopicOperationEmptyResponse = 17004, // I-FCM017004 + // FIRMessagingUtilities.m + kFIRMessagingMessageCodeUtilities000 = 18000, // I-FCM018000 + kFIRMessagingMessageCodeUtilities001 = 18001, // I-FCM018001 + kFIRMessagingMessageCodeUtilities002 = 18002, // I-FCM018002 + // FIRMessagingAnalytics.m + kFIRMessagingMessageCodeAnalytics000 = 19000, // I-FCM019000 + kFIRMessagingMessageCodeAnalytics001 = 19001, // I-FCM019001 + kFIRMessagingMessageCodeAnalytics002 = 19002, // I-FCM019002 + kFIRMessagingMessageCodeAnalytics003 = 19003, // I-FCM019003 + kFIRMessagingMessageCodeAnalytics004 = 19004, // I-FCM019004 + kFIRMessagingMessageCodeAnalytics005 = 19005, // I-FCM019005 + kFIRMessagingMessageCodeAnalyticsInvalidEvent = 19006, // I-FCM019006 + kFIRMessagingMessageCodeAnalytics007 = 19007, // I-FCM019007 + kFIRMessagingMessageCodeAnalyticsCouldNotInvokeAnalyticsLog = 19008, // I-FCM019008 + + // FIRMessagingExtensionHelper.m + kFIRMessagingServiceExtensionImageInvalidURL = 20000, + kFIRMessagingServiceExtensionImageNotDownloaded = 20001, + kFIRMessagingServiceExtensionLocalFileNotCreated = 20002, + kFIRMessagingServiceExtensionImageNotAttached = 20003, + + // FIRMessagingCodedInputStream.m + kFIRMessagingCodeInputStreamInvalidParameters = 21000, + +}; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessaging.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessaging.m new file mode 100644 index 00000000..4d14f92f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessaging.m @@ -0,0 +1,1144 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#if !__has_feature(objc_arc) +#error FIRMessagingLib should be compiled with ARC. +#endif + +#import <FirebaseInstanceID/FIRInstanceID_Private.h> +#import <FirebaseInstanceID/FirebaseInstanceID.h> +#import <FirebaseMessaging/FIRMessaging.h> +#import <FirebaseMessaging/FIRMessagingExtensionHelper.h> +#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h" +#import "GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h" +#import "GoogleUtilities/Reachability/Private/GULReachabilityChecker.h" +#import "GoogleUtilities/UserDefaults/Private/GULUserDefaults.h" +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +#import "FirebaseMessaging/Sources/FIRMessagingAnalytics.h" +#import "FirebaseMessaging/Sources/FIRMessagingClient.h" +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" +#import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h" +#import "FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPubSub.h" +#import "FirebaseMessaging/Sources/FIRMessagingReceiver.h" +#import "FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.h" +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessagingVersionUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" + +static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps"; +static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com"; +static NSString *const kFIRMessagingDefaultTokenScope = @"*"; +static NSString *const kFIRMessagingFCMTokenFetchAPNSOption = @"apns_token"; + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +const NSNotificationName FIRMessagingSendSuccessNotification = + @"com.firebase.messaging.notif.send-success"; +const NSNotificationName FIRMessagingSendErrorNotification = + @"com.firebase.messaging.notif.send-error"; +const NSNotificationName FIRMessagingMessagesDeletedNotification = + @"com.firebase.messaging.notif.messages-deleted"; +const NSNotificationName FIRMessagingConnectionStateChangedNotification = + @"com.firebase.messaging.notif.connection-state-changed"; +const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification = + @"com.firebase.messaging.notif.fcm-token-refreshed"; +#else +NSString *const FIRMessagingSendSuccessNotification = @"com.firebase.messaging.notif.send-success"; +NSString *const FIRMessagingSendErrorNotification = @"com.firebase.messaging.notif.send-error"; +NSString *const FIRMessagingMessagesDeletedNotification = + @"com.firebase.messaging.notif.messages-deleted"; +NSString *const FIRMessagingConnectionStateChangedNotification = + @"com.firebase.messaging.notif.connection-state-changed"; +NSString *const FIRMessagingRegistrationTokenRefreshedNotification = + @"com.firebase.messaging.notif.fcm-token-refreshed"; +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled = + @"com.firebase.messaging.auto-init.enabled"; // Auto Init Enabled key stored in NSUserDefaults + +NSString *const kFIRMessagingAPNSTokenType = + @"APNSTokenType"; // APNS Token type key stored in user info. + +NSString *const kFIRMessagingPlistAutoInitEnabled = + @"FirebaseMessagingAutoInitEnabled"; // Auto Init Enabled key stored in Info.plist + +const BOOL FIRMessagingIsAPNSSyncMessage(NSDictionary *message) { + if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) { + NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey]; + if (aps && [aps isKindOfClass:[NSDictionary class]]) { + return [aps[kFIRMessagingMessageAPNSContentAvailableKey] boolValue]; + } + } + return NO; +} + +BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) { + return [FIRMessagingContextManagerService isContextManagerMessage:message]; +} + +@interface FIRMessagingMessageInfo () + +@property(nonatomic, readwrite, assign) FIRMessagingMessageStatus status; + +@end + +@implementation FIRMessagingMessageInfo + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithStatus:(FIRMessagingMessageStatus)status { + self = [super init]; + if (self) { + _status = status; + } + return self; +} + +@end + +#pragma mark - for iOS 10 compatibility +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +@implementation FIRMessagingRemoteMessage +#pragma clang diagnostic pop + +- (instancetype)init { + self = [super init]; + if (self) { + _appData = [[NSMutableDictionary alloc] init]; + } + + return self; +} + +@end + +@interface FIRMessaging () <FIRMessagingClientDelegate, + FIRMessagingReceiverDelegate, + GULReachabilityDelegate> + +// FIRApp properties +@property(nonatomic, readwrite, strong) NSData *apnsTokenData; +@property(nonatomic, readwrite, strong) NSString *defaultFcmToken; + +@property(nonatomic, readwrite, strong) FIRInstanceID *instanceID; + +@property(nonatomic, readwrite, strong) FIRMessagingClient *client; +@property(nonatomic, readwrite, strong) GULReachabilityChecker *reachability; +@property(nonatomic, readwrite, strong) FIRMessagingDataMessageManager *dataMessageManager; +@property(nonatomic, readwrite, strong) FIRMessagingPubSub *pubsub; +@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, strong) FIRMessagingReceiver *receiver; +@property(nonatomic, readwrite, strong) FIRMessagingSyncMessageManager *syncMessageManager; +@property(nonatomic, readwrite, strong) GULUserDefaults *messagingUserDefaults; + +/// Message ID's logged for analytics. This prevents us from logging the same message twice +/// which can happen if the user inadvertently calls `appDidReceiveMessage` along with us +/// calling it implicitly during swizzling. +@property(nonatomic, readwrite, strong) NSMutableSet *loggedMessageIDs; +@property(nonatomic, readwrite, strong) id<FIRAnalyticsInterop> _Nullable analytics; + +@end + +// Messaging doesn't provide any functionality to other components, +// so it provides a private, empty protocol that it conforms to and use it for registration. + +@protocol FIRMessagingInstanceProvider +@end + +@interface FIRMessaging () <FIRMessagingInstanceProvider, FIRLibrary> +@end + +@implementation FIRMessaging + ++ (FIRMessaging *)messaging { + FIRApp *defaultApp = [FIRApp defaultApp]; // Missing configure will be logged here. + id<FIRMessagingInstanceProvider> instance = + FIR_COMPONENT(FIRMessagingInstanceProvider, defaultApp.container); + + // We know the instance coming from the container is a FIRMessaging instance, cast it and move on. + return (FIRMessaging *)instance; +} + ++ (FIRMessagingExtensionHelper *)extensionHelper { + static dispatch_once_t once; + static FIRMessagingExtensionHelper *extensionHelper; + dispatch_once(&once, ^{ + extensionHelper = [[FIRMessagingExtensionHelper alloc] init]; + }); + return extensionHelper; +} + +- (instancetype)initWithAnalytics:(nullable id<FIRAnalyticsInterop>)analytics + withInstanceID:(FIRInstanceID *)instanceID + withUserDefaults:(GULUserDefaults *)defaults { + self = [super init]; + if (self != nil) { + _loggedMessageIDs = [NSMutableSet set]; + _instanceID = instanceID; + _messagingUserDefaults = defaults; + _analytics = analytics; + } + return self; +} + +- (void)dealloc { + [self.reachability stop]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self teardown]; +} + +#pragma mark - Config + ++ (void)load { + [FIRApp registerInternalLibrary:(Class<FIRLibrary>)self + withName:@"fire-fcm" + withVersion:FIRMessagingCurrentLibraryVersion()]; +} + ++ (nonnull NSArray<FIRComponent *> *)componentsToRegister { + FIRDependency *analyticsDep = [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop) + isRequired:NO]; + FIRComponentCreationBlock creationBlock = + ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + if (!container.app.isDefaultApp) { + // Only start for the default FIRApp. + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeFIRApp001, + @"Firebase Messaging only works with the default app."); + return nil; + } + + // Ensure it's cached so it returns the same instance every time messaging is called. + *isCacheable = YES; + id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container); + FIRMessaging *messaging = + [[FIRMessaging alloc] initWithAnalytics:analytics + withInstanceID:[FIRInstanceID instanceID] + withUserDefaults:[GULUserDefaults standardUserDefaults]]; + [messaging start]; + [messaging configureNotificationSwizzlingIfEnabled]; + return messaging; + }; + FIRComponent *messagingProvider = + [FIRComponent componentWithProtocol:@protocol(FIRMessagingInstanceProvider) + instantiationTiming:FIRInstantiationTimingEagerInDefaultApp + dependencies:@[ analyticsDep ] + creationBlock:creationBlock]; + + return @[ messagingProvider ]; +} + +- (void)configureNotificationSwizzlingIfEnabled { + // Swizzle remote-notification-related methods (app delegate and UNUserNotificationCenter) + if ([FIRMessagingRemoteNotificationsProxy canSwizzleMethods]) { + NSString *docsURLString = @"https://firebase.google.com/docs/cloud-messaging/ios/client" + @"#method_swizzling_in_firebase_messaging"; + FIRMessagingLoggerNotice(kFIRMessagingMessageCodeFIRApp000, + @"FIRMessaging Remote Notifications proxy enabled, will swizzle " + @"remote notification receiver handlers. If you'd prefer to manually " + @"integrate Firebase Messaging, add \"%@\" to your Info.plist, " + @"and set it to NO. Follow the instructions at:\n%@\nto ensure " + @"proper integration.", + kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey, + docsURLString); + [[FIRMessagingRemoteNotificationsProxy sharedProxy] swizzleMethodsIfPossible]; + } +} + +- (void)start { + [self setupFileManagerSubDirectory]; + [self setupNotificationListeners]; + +#if !TARGET_OS_WATCH + // Print the library version for logging. + NSString *currentLibraryVersion = FIRMessagingCurrentLibraryVersion(); + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessagingPrintLibraryVersion, + @"FIRMessaging library version %@", currentLibraryVersion); + + [self setupReceiver]; + + NSString *hostname = kFIRMessagingReachabilityHostname; + self.reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self + withHost:hostname]; + [self.reachability start]; + + // setup FIRMessaging objects + [self setupRmqManager]; + [self setupClient]; + [self setupSyncMessageManager]; + [self setupDataMessageManager]; + [self setupTopics]; + +#endif +} + +- (void)setupFileManagerSubDirectory { + if (![[self class] hasSubDirectory:kFIRMessagingSubDirectoryName]) { + [[self class] createSubDirectory:kFIRMessagingSubDirectoryName]; + } +} + +- (void)setupNotificationListeners { + // To prevent multiple notifications remove self as observer for all events. + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self]; + [center addObserver:self + selector:@selector(defaultInstanceIDTokenWasRefreshed:) + name:kFIRMessagingRegistrationTokenRefreshNotification + object:nil]; +#if TARGET_OS_IOS || TARGET_OS_TV + [center addObserver:self + selector:@selector(applicationStateChanged) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + [center addObserver:self + selector:@selector(applicationStateChanged) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; +#endif +} + +- (void)setupReceiver { + self.receiver = [[FIRMessagingReceiver alloc] init]; + self.receiver.delegate = self; +} + +- (void)setupClient { + self.client = [[FIRMessagingClient alloc] initWithDelegate:self + reachability:self.reachability + rmq2Manager:self.rmq2Manager]; +} + +- (void)setupDataMessageManager { + self.dataMessageManager = + [[FIRMessagingDataMessageManager alloc] initWithDelegate:self.receiver + client:self.client + rmq2Manager:self.rmq2Manager + syncMessageManager:self.syncMessageManager]; + + [self.dataMessageManager refreshDelayedMessages]; + [self.client setDataMessageManager:self.dataMessageManager]; +} + +- (void)setupRmqManager { + self.rmq2Manager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:@"rmq2"]; + [self.rmq2Manager loadRmqId]; +} + +- (void)setupTopics { + if (!self.client) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeInvalidClient, + @"Invalid nil client before init pubsub."); + } + self.pubsub = [[FIRMessagingPubSub alloc] initWithClient:self.client]; +} + +- (void)setupSyncMessageManager { + self.syncMessageManager = + [[FIRMessagingSyncMessageManager alloc] initWithRmqManager:self.rmq2Manager]; + [self.syncMessageManager removeExpiredSyncMessages]; +} + +- (void)teardown { + [self.client teardown]; + self.pubsub = nil; + self.syncMessageManager = nil; + self.rmq2Manager = nil; + self.dataMessageManager = nil; + self.client = nil; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging001, @"Did successfully teardown"); +} + +#pragma mark - Messages + +- (FIRMessagingMessageInfo *)appDidReceiveMessage:(NSDictionary *)message { + if (!message.count) { + return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusUnknown]; + } + + // For downstream messages that go via MCS we should strip out this key before sending + // the message to the device. + BOOL isOldMessage = NO; + NSString *messageID = message[kFIRMessagingMessageIDKey]; + if (messageID.length) { + [self.rmq2Manager saveS2dMessageWithRmqId:messageID]; + + BOOL isSyncMessage = FIRMessagingIsAPNSSyncMessage(message); + if (isSyncMessage) { + isOldMessage = [self.syncMessageManager didReceiveAPNSSyncMessage:message]; + } + + // Prevent duplicates by keeping a cache of all the logged messages during each session. + // The duplicates only happen when the 3P app calls `appDidReceiveMessage:` along with + // us swizzling their implementation to call the same method implicitly. + // We need to rule out the contextual message because it shares the same message ID + // as the local notification it will schedule. And because it is also a APNSSync message + // its duplication is already checked previously. + if (!isOldMessage && !FIRMessagingIsContextManagerMessage(message)) { + isOldMessage = [self.loggedMessageIDs containsObject:messageID]; + if (!isOldMessage) { + [self.loggedMessageIDs addObject:messageID]; + } + } + } + + if (!isOldMessage) { + [FIRMessagingAnalytics logMessage:message toAnalytics:_analytics]; + [self handleContextManagerMessage:message]; + [self handleIncomingLinkIfNeededFromMessage:message]; + } + return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusNew]; +} + +- (BOOL)handleContextManagerMessage:(NSDictionary *)message { + if (FIRMessagingIsContextManagerMessage(message)) { + return [FIRMessagingContextManagerService handleContextManagerMessage:message]; + } + return NO; +} + +- (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message { +#if TARGET_OS_IOS || TARGET_OS_TV + NSURL *url = [self linkURLFromMessage:message]; + if (url == nil) { + return; + } + if (![NSThread isMainThread]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self handleIncomingLinkIfNeededFromMessage:message]; + }); + return; + } + UIApplication *application = [GULAppDelegateSwizzler sharedApplication]; + if (!application) { + return; + } + id<UIApplicationDelegate> appDelegate = application.delegate; + SEL continueUserActivitySelector = @selector(application: + continueUserActivity:restorationHandler:); + + SEL openURLWithOptionsSelector = @selector(application:openURL:options:); + SEL openURLWithSourceApplicationSelector = @selector(application: + openURL:sourceApplication:annotation:); +#if TARGET_OS_IOS + SEL handleOpenURLSelector = @selector(application:handleOpenURL:); +#endif + // Due to FIRAAppDelegateProxy swizzling, this selector will most likely get chosen, whether or + // not the actual application has implemented + // |application:continueUserActivity:restorationHandler:|. A warning will be displayed to the user + // if they haven't implemented it. + if ([NSUserActivity class] != nil && + [appDelegate respondsToSelector:continueUserActivitySelector]) { + NSUserActivity *userActivity = + [[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb]; + userActivity.webpageURL = url; + [appDelegate application:application + continueUserActivity:userActivity + restorationHandler:^(NSArray *_Nullable restorableObjects){ + // Do nothing, as we don't support the app calling this block + }]; + + } else if ([appDelegate respondsToSelector:openURLWithOptionsSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + [appDelegate application:application openURL:url options:@{}]; +#pragma clang diagnostic pop + // Similarly, |application:openURL:sourceApplication:annotation:| will also always be called, + // due to the default swizzling done by FIRAAppDelegateProxy in Firebase Analytics + } else if ([appDelegate respondsToSelector:openURLWithSourceApplicationSelector]) { +#if TARGET_OS_IOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [appDelegate application:application + openURL:url + sourceApplication:FIRMessagingAppIdentifier() + annotation:@{}]; +#pragma clang diagnostic pop + } else if ([appDelegate respondsToSelector:handleOpenURLSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [appDelegate application:application handleOpenURL:url]; +#pragma clang diagnostic pop +#endif + } +#endif +} + +- (NSURL *)linkURLFromMessage:(NSDictionary *)message { + NSString *urlString = message[kFIRMessagingMessageLinkKey]; + if (urlString == nil || ![urlString isKindOfClass:[NSString class]] || urlString.length == 0) { + return nil; + } + NSURL *url = [NSURL URLWithString:urlString]; + return url; +} + +#pragma mark - APNS + +- (NSData *)APNSToken { + return self.apnsTokenData; +} + +- (void)setAPNSToken:(NSData *)APNSToken { + [self setAPNSToken:APNSToken type:FIRMessagingAPNSTokenTypeUnknown]; +} + +- (void)setAPNSToken:(NSData *)apnsToken type:(FIRMessagingAPNSTokenType)type { + if ([apnsToken isEqual:self.apnsTokenData]) { + return; + } + self.apnsTokenData = apnsToken; + + // Notify InstanceID that APNS Token has been set. + NSDictionary *userInfo = @{kFIRMessagingAPNSTokenType : @(type)}; + NSNotification *notification = + [NSNotification notificationWithName:kFIRMessagingAPNSTokenNotification + object:[apnsToken copy] + userInfo:userInfo]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; +} + +#pragma mark - FCM + +- (BOOL)isAutoInitEnabled { + // Defer to the class method since we're just reading from regular userDefaults and we need to + // read this from IID without instantiating the Messaging singleton. + return [[self class] isAutoInitEnabledWithUserDefaults:_messagingUserDefaults]; +} + +/// Checks if Messaging auto-init is enabled in the user defaults instance passed in. This is +/// exposed as a class property for IID to fetch the property without instantiating an instance of +/// Messaging. Since Messaging can only be used with the default FIRApp, we can have one point of +/// entry without context of which FIRApp instance is being used. +/// ** THIS METHOD IS DEPENDED ON INTERNALLY BY IID USING REFLECTION. PLEASE DO NOT CHANGE THE +/// SIGNATURE, AS IT WOULD BREAK AUTOINIT FUNCTIONALITY WITHIN IID. ** ++ (BOOL)isAutoInitEnabledWithUserDefaults:(GULUserDefaults *)userDefaults { + // Check storage + id isAutoInitEnabledObject = + [userDefaults objectForKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled]; + if (isAutoInitEnabledObject) { + return [isAutoInitEnabledObject boolValue]; + } + + // Check Info.plist + isAutoInitEnabledObject = + [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRMessagingPlistAutoInitEnabled]; + if (isAutoInitEnabledObject) { + return [isAutoInitEnabledObject boolValue]; + } + + // If none of above exists, we default to the global switch that comes from FIRApp. + return [[FIRApp defaultApp] isDataCollectionDefaultEnabled]; +} + +- (void)setAutoInitEnabled:(BOOL)autoInitEnabled { + BOOL isFCMAutoInitEnabled = [self isAutoInitEnabled]; + [_messagingUserDefaults setBool:autoInitEnabled + forKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled]; + [_messagingUserDefaults synchronize]; + if (!isFCMAutoInitEnabled && autoInitEnabled) { + self.defaultFcmToken = self.instanceID.token; + } +} + +- (NSString *)FCMToken { + NSString *token = self.defaultFcmToken; + if (!token) { + // We may not have received it from Instance ID yet (via NSNotification), so extract it directly + token = self.instanceID.token; + } + return token; +} + +- (void)retrieveFCMTokenForSenderID:(nonnull NSString *)senderID + completion:(nonnull FIRMessagingFCMTokenFetchCompletion)completion { + if (!senderID.length) { + NSString *description = @"Couldn't fetch token because a Sender ID was not supplied. A valid " + @"Sender ID is required to fetch an FCM token"; + FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch, @"%@", + description); + if (completion) { + NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidRequest + failureReason:description]; + completion(nil, error); + } + return; + } + NSDictionary *options = nil; + if (self.APNSToken) { + options = @{kFIRMessagingFCMTokenFetchAPNSOption : self.APNSToken}; + } else { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeAPNSTokenNotAvailableDuringTokenFetch, + @"APNS device token not set before retrieving FCM Token for Sender ID " + @"'%@'. Notifications to this FCM Token will not be delivered over APNS." + @"Be sure to re-retrieve the FCM token once the APNS device token is " + @"set.", + senderID); + } + [self.instanceID tokenWithAuthorizedEntity:senderID + scope:kFIRMessagingDefaultTokenScope + options:options + handler:completion]; +} + +- (void)deleteFCMTokenForSenderID:(nonnull NSString *)senderID + completion:(nonnull FIRMessagingDeleteFCMTokenCompletion)completion { + if (!senderID.length) { + NSString *description = @"Couldn't delete token because a Sender ID was not supplied. A " + @"valid Sender ID is required to delete an FCM token"; + FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete, @"%@", + description); + if (completion) { + NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidRequest + failureReason:description]; + completion(error); + } + return; + } + [self.instanceID deleteTokenWithAuthorizedEntity:senderID + scope:kFIRMessagingDefaultTokenScope + handler:completion]; +} + +#pragma mark - FIRMessagingDelegate helper methods +- (void)setDelegate:(id<FIRMessagingDelegate>)delegate { + _delegate = delegate; + [self validateDelegateConformsToTokenAvailabilityMethods]; +} + +// Check if the delegate conforms to |didReceiveRegistrationToken:| +// and display a warning to the developer if not. +// NOTE: Once |didReceiveRegistrationToken:| can be made a required method, this +// check can be removed. +- (void)validateDelegateConformsToTokenAvailabilityMethods { + if (self.delegate && ![self.delegate respondsToSelector:@selector(messaging: + didReceiveRegistrationToken:)]) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented, + @"The object %@ does not respond to " + @"-messaging:didReceiveRegistrationToken:. Please implement " + @"-messaging:didReceiveRegistrationToken: to be provided with an FCM " + @"token.", + self.delegate.description); + } +} + +- (void)notifyDelegateOfFCMTokenAvailability { + __weak FIRMessaging *weakSelf = self; + if (![NSThread isMainThread]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf notifyDelegateOfFCMTokenAvailability]; + }); + return; + } + if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { + [self.delegate messaging:self didReceiveRegistrationToken:self.defaultFcmToken]; + } + // Should always trigger the token refresh notification when the delegate method is called + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification + object:self.defaultFcmToken]; +} + +#pragma mark - Application State Changes + +- (void)applicationStateChanged { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (self.shouldEstablishDirectChannel) { + [self updateAutomaticClientConnection]; + } +#pragma clang diagnostic pop +} + +#pragma mark - Direct Channel + +- (void)setShouldEstablishDirectChannel:(BOOL)shouldEstablishDirectChannel { + if (_shouldEstablishDirectChannel == shouldEstablishDirectChannel) { + return; + } + _shouldEstablishDirectChannel = shouldEstablishDirectChannel; + [self updateAutomaticClientConnection]; +} + +- (BOOL)isDirectChannelEstablished { + return self.client.isConnectionActive; +} + +- (BOOL)shouldBeConnectedAutomatically { +#if TARGET_OS_OSX || TARGET_OS_WATCH + return NO; +#else + // We require a token from Instance ID + NSString *token = self.defaultFcmToken; + // Only on foreground connections + UIApplication *application = [GULAppDelegateSwizzler sharedApplication]; + if (!application) { + return NO; + } + UIApplicationState applicationState = application.applicationState; + BOOL shouldBeConnected = _shouldEstablishDirectChannel && (token.length > 0) && + applicationState == UIApplicationStateActive; + return shouldBeConnected; +#endif +} + +- (void)updateAutomaticClientConnection { + if (![NSThread isMainThread]) { + // Call this method from the main thread + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateAutomaticClientConnection]; + }); + return; + } + BOOL shouldBeConnected = [self shouldBeConnectedAutomatically]; + if (shouldBeConnected && !self.client.isConnected) { + [self.client connectWithHandler:^(NSError *error) { + if (!error) { + // It means we connected. Fire connection change notification + [self notifyOfDirectChannelConnectionChange]; + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeDirectChannelConnectionFailed, + @"Failed to connect to direct channel, error: %@\n", error); + } + }]; + } else if (!shouldBeConnected && self.client.isConnected) { + [self.client disconnect]; + [self notifyOfDirectChannelConnectionChange]; + } +} + +- (void)notifyOfDirectChannelConnectionChange { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [center postNotificationName:FIRMessagingConnectionStateChangedNotification object:self]; +#pragma clang diagnostic pop +} + +#pragma mark - Topics + ++ (NSString *)normalizeTopic:(NSString *)topic { + if (!topic.length) { + return nil; + } + if (![FIRMessagingPubSub hasTopicsPrefix:topic]) { + topic = [FIRMessagingPubSub addPrefixToTopic:topic]; + } + if ([FIRMessagingPubSub isValidTopicWithPrefix:topic]) { + return [topic copy]; + } + return nil; +} + +- (void)subscribeToTopic:(NSString *)topic { + [self subscribeToTopic:topic completion:nil]; +} + +- (void)subscribeToTopic:(NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion { + if ([FIRMessagingPubSub hasTopicsPrefix:topic]) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated, + @"Format '%@' is deprecated. Only '%@' should be used in " + @"subscribeToTopic.", + topic, [FIRMessagingPubSub removePrefixFromTopic:topic]); + } + __weak FIRMessaging *weakSelf = self; + [self.instanceID instanceIDWithHandler:^(FIRInstanceIDResult *_Nullable result, + NSError *_Nullable error) { + if (error) { + FIRMessagingLoggerError( + kFIRMessagingMessageCodeMessaging010, + @"The subscription operation failed due to an error getting the FCM token: %@.", error); + if (completion) { + completion(error); + } + return; + } + FIRMessaging *strongSelf = weakSelf; + NSString *normalizeTopic = [[strongSelf class] normalizeTopic:topic]; + if (normalizeTopic.length) { + [strongSelf.pubsub subscribeToTopic:normalizeTopic handler:completion]; + return; + } + NSString *failureReason = + [NSString stringWithFormat:@"Cannot parse topic name: '%@'. Will not subscribe.", topic]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging009, @"%@", failureReason); + if (completion) { + completion([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName + failureReason:failureReason]); + } + }]; +} + +- (void)unsubscribeFromTopic:(NSString *)topic { + [self unsubscribeFromTopic:topic completion:nil]; +} + +- (void)unsubscribeFromTopic:(NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion { + if ([FIRMessagingPubSub hasTopicsPrefix:topic]) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated, + @"Format '%@' is deprecated. Only '%@' should be used in " + @"unsubscribeFromTopic.", + topic, [FIRMessagingPubSub removePrefixFromTopic:topic]); + } + __weak FIRMessaging *weakSelf = self; + [self.instanceID instanceIDWithHandler:^(FIRInstanceIDResult *_Nullable result, + NSError *_Nullable error) { + if (error) { + FIRMessagingLoggerError( + kFIRMessagingMessageCodeMessaging012, + @"The unsubscription operation failed due to an error getting the FCM token: %@.", error); + if (completion) { + completion(error); + } + return; + } + FIRMessaging *strongSelf = weakSelf; + NSString *normalizeTopic = [[strongSelf class] normalizeTopic:topic]; + if (normalizeTopic.length) { + [strongSelf.pubsub unsubscribeFromTopic:normalizeTopic handler:completion]; + return; + } + NSString *failureReason = + [NSString stringWithFormat:@"Cannot parse topic name: '%@'. Will not unsubscribe.", topic]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging011, @"%@", failureReason); + if (completion) { + completion([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName + failureReason:failureReason]); + } + }]; +} + +#pragma mark - Send + +- (void)sendMessage:(NSDictionary *)message + to:(NSString *)to + withMessageID:(NSString *)messageID + timeToLive:(int64_t)ttl { + NSMutableDictionary *fcmMessage = [[self class] createFIRMessagingMessageWithMessage:message + to:to + withID:messageID + timeToLive:ttl + delay:0]; + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessaging013, + @"Sending message: %@ with id: %@ to %@.", message, messageID, to); + [self.dataMessageManager sendDataMessageStanza:fcmMessage]; +} + ++ (NSMutableDictionary *)createFIRMessagingMessageWithMessage:(NSDictionary *)message + to:(NSString *)to + withID:(NSString *)msgID + timeToLive:(int64_t)ttl + delay:(int)delay { + NSMutableDictionary *fcmMessage = [NSMutableDictionary dictionary]; + fcmMessage[kFIRMessagingSendTo] = [to copy]; + fcmMessage[kFIRMessagingSendMessageID] = msgID ? [msgID copy] : @""; + fcmMessage[kFIRMessagingSendTTL] = @(ttl); + fcmMessage[kFIRMessagingSendDelay] = @(delay); + fcmMessage[KFIRMessagingSendMessageAppData] = + [NSMutableDictionary dictionaryWithDictionary:message]; + return fcmMessage; +} + +#pragma mark - IID dependencies + ++ (NSString *)FIRMessagingSDKVersion { + return FIRMessagingCurrentLibraryVersion(); +} + ++ (NSString *)FIRMessagingSDKCurrentLocale { + return [self currentLocale]; +} + +#pragma mark - FIRMessagingReceiverDelegate + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void)receiver:(FIRMessagingReceiver *)receiver + receivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage { + if ([self.delegate respondsToSelector:@selector(messaging:didReceiveMessage:)]) { + [self appDidReceiveMessage:remoteMessage.appData]; +#pragma clang diagnostic ignored "-Wunguarded-availability" + [self.delegate messaging:self didReceiveMessage:remoteMessage]; +#pragma clang diagnostic pop + } else { + // Delegate methods weren't implemented, so messages are being dropped, log a warning + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeRemoteMessageDelegateMethodNotImplemented, + @"FIRMessaging received data-message, but FIRMessagingDelegate's" + @"-messaging:didReceiveMessage: not implemented"); + } +} + +#pragma mark - GULReachabilityDelegate + +- (void)reachability:(GULReachabilityChecker *)reachability + statusChanged:(GULReachabilityStatus)status { + [self onNetworkStatusChanged]; +} + +#pragma mark - Network + +- (void)onNetworkStatusChanged { + if (![self.client isConnected] && [self isNetworkAvailable]) { + if (self.client.shouldStayConnected) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging014, + @"Attempting to establish direct channel."); + [self.client retryConnectionImmediately:YES]; + } + [self.pubsub scheduleSync:YES]; + } +} + +- (BOOL)isNetworkAvailable { + GULReachabilityStatus status = self.reachability.reachabilityStatus; + return (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi); +} + +- (FIRMessagingNetworkStatus)networkType { + GULReachabilityStatus status = self.reachability.reachabilityStatus; + if (![self isNetworkAvailable]) { + return kFIRMessagingReachabilityNotReachable; + } else if (status == kGULReachabilityViaCellular) { + return kFIRMessagingReachabilityReachableViaWWAN; + } else { + return kFIRMessagingReachabilityReachableViaWiFi; + } +} + +#pragma mark - Notifications + +- (void)defaultInstanceIDTokenWasRefreshed:(NSNotification *)notification { + if (notification.object && ![notification.object isKindOfClass:[NSString class]]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging015, + @"Invalid default FCM token type %@", + NSStringFromClass([notification.object class])); + return; + } + // Retrieve the Instance ID default token, and should notify delegate and + // trigger notification as long as the token is different from previous state. + NSString *oldToken = self.defaultFcmToken; + self.defaultFcmToken = [(NSString *)notification.object copy]; + if ((self.defaultFcmToken.length && oldToken.length && + ![self.defaultFcmToken isEqualToString:oldToken]) || + self.defaultFcmToken.length != oldToken.length) { + [self notifyDelegateOfFCMTokenAvailability]; + [self.pubsub scheduleSync:YES]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (self.shouldEstablishDirectChannel) { + [self updateAutomaticClientConnection]; + } +#pragma clang diagnostic pop + } +} + +#pragma mark - Application Support Directory + ++ (BOOL)hasSubDirectory:(NSString *)subDirectoryName { + NSString *subDirectoryPath = [self pathForSubDirectory:subDirectoryName]; + BOOL isDirectory; + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&isDirectory]) { + return NO; + } else if (!isDirectory) { + return NO; + } + return YES; +} + ++ (NSString *)pathForSubDirectory:(NSString *)subDirectoryName { + NSArray *directoryPaths = + NSSearchPathForDirectoriesInDomains(FIRMessagingSupportedDirectory(), NSUserDomainMask, YES); + NSString *dirPath = directoryPaths.lastObject; + NSArray *components = @[ dirPath, subDirectoryName ]; + return [NSString pathWithComponents:components]; +} + ++ (BOOL)createSubDirectory:(NSString *)subDirectoryName { + NSString *subDirectoryPath = [self pathForSubDirectory:subDirectoryName]; + BOOL hasSubDirectory; + + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&hasSubDirectory]) { + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtPath:subDirectoryPath + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging017, + @"Cannot create directory %@, error: %@", subDirectoryPath, error); + return NO; + } + } else { + if (!hasSubDirectory) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging018, + @"Found file instead of directory at %@", subDirectoryPath); + return NO; + } + } + return YES; +} + +#pragma mark - Locales + ++ (NSString *)currentLocale { + NSArray *locales = [self firebaseLocales]; + NSArray *preferredLocalizations = + [NSBundle preferredLocalizationsFromArray:locales + forPreferences:[NSLocale preferredLanguages]]; + NSString *legalDocsLanguage = [preferredLocalizations firstObject]; + // Use en as the default language + return legalDocsLanguage ? legalDocsLanguage : @"en"; +} + ++ (NSArray *)firebaseLocales { + NSMutableArray *locales = [NSMutableArray array]; + NSDictionary *localesMap = [self firebaselocalesMap]; + for (NSString *key in localesMap) { + [locales addObjectsFromArray:localesMap[key]]; + } + return locales; +} + ++ (NSDictionary *)firebaselocalesMap { + return @{ + // Albanian + @"sq" : @[ @"sq_AL" ], + // Belarusian + @"be" : @[ @"be_BY" ], + // Bulgarian + @"bg" : @[ @"bg_BG" ], + // Catalan + @"ca" : @[ @"ca", @"ca_ES" ], + // Croatian + @"hr" : @[ @"hr", @"hr_HR" ], + // Czech + @"cs" : @[ @"cs", @"cs_CZ" ], + // Danish + @"da" : @[ @"da", @"da_DK" ], + // Estonian + @"et" : @[ @"et_EE" ], + // Finnish + @"fi" : @[ @"fi", @"fi_FI" ], + // Hebrew + @"he" : @[ @"he", @"iw_IL" ], + // Hindi + @"hi" : @[ @"hi_IN" ], + // Hungarian + @"hu" : @[ @"hu", @"hu_HU" ], + // Icelandic + @"is" : @[ @"is_IS" ], + // Indonesian + @"id" : @[ @"id", @"in_ID", @"id_ID" ], + // Irish + @"ga" : @[ @"ga_IE" ], + // Korean + @"ko" : @[ @"ko", @"ko_KR", @"ko-KR" ], + // Latvian + @"lv" : @[ @"lv_LV" ], + // Lithuanian + @"lt" : @[ @"lt_LT" ], + // Macedonian + @"mk" : @[ @"mk_MK" ], + // Malay + @"ms" : @[ @"ms_MY" ], + // Maltese + @"mt" : @[ @"mt_MT" ], + // Polish + @"pl" : @[ @"pl", @"pl_PL", @"pl-PL" ], + // Romanian + @"ro" : @[ @"ro", @"ro_RO" ], + // Russian + @"ru" : @[ @"ru_RU", @"ru", @"ru_BY", @"ru_KZ", @"ru-RU" ], + // Slovak + @"sk" : @[ @"sk", @"sk_SK" ], + // Slovenian + @"sl" : @[ @"sl_SI" ], + // Swedish + @"sv" : @[ @"sv", @"sv_SE", @"sv-SE" ], + // Turkish + @"tr" : @[ @"tr", @"tr-TR", @"tr_TR" ], + // Ukrainian + @"uk" : @[ @"uk", @"uk_UA" ], + // Vietnamese + @"vi" : @[ @"vi", @"vi_VN" ], + // The following are groups of locales or locales that sub-divide a + // language). + // Arabic + @"ar" : @[ + @"ar", @"ar_DZ", @"ar_BH", @"ar_EG", @"ar_IQ", @"ar_JO", @"ar_KW", + @"ar_LB", @"ar_LY", @"ar_MA", @"ar_OM", @"ar_QA", @"ar_SA", @"ar_SD", + @"ar_SY", @"ar_TN", @"ar_AE", @"ar_YE", @"ar_GB", @"ar-IQ", @"ar_US" + ], + // Simplified Chinese + @"zh_Hans" : @[ @"zh_CN", @"zh_SG", @"zh-Hans" ], + // Traditional Chinese + @"zh_Hant" : @[ @"zh_HK", @"zh_TW", @"zh-Hant", @"zh-HK", @"zh-TW" ], + // Dutch + @"nl" : @[ @"nl", @"nl_BE", @"nl_NL", @"nl-NL" ], + // English + @"en" : @[ + @"en", @"en_AU", @"en_CA", @"en_IN", @"en_IE", @"en_MT", @"en_NZ", @"en_PH", + @"en_SG", @"en_ZA", @"en_GB", @"en_US", @"en_AE", @"en-AE", @"en_AS", @"en-AU", + @"en_BD", @"en-CA", @"en_EG", @"en_ES", @"en_GB", @"en-GB", @"en_HK", @"en_ID", + @"en-IN", @"en_NG", @"en-PH", @"en_PK", @"en-SG", @"en-US" + ], + // French + + @"fr" : + @[ @"fr", @"fr_BE", @"fr_CA", @"fr_FR", @"fr_LU", @"fr_CH", @"fr-CA", @"fr-FR", @"fr_MA" ], + // German + @"de" : @[ @"de", @"de_AT", @"de_DE", @"de_LU", @"de_CH", @"de-DE" ], + // Greek + @"el" : @[ @"el", @"el_CY", @"el_GR" ], + // Italian + @"it" : @[ @"it", @"it_IT", @"it_CH", @"it-IT" ], + // Japanese + @"ja" : @[ @"ja", @"ja_JP", @"ja_JP_JP", @"ja-JP" ], + // Norwegian + @"no" : @[ @"nb", @"no_NO", @"no_NO_NY", @"nb_NO" ], + // Brazilian Portuguese + @"pt_BR" : @[ @"pt_BR", @"pt-BR" ], + // European Portuguese + @"pt_PT" : @[ @"pt", @"pt_PT", @"pt-PT" ], + // Serbian + @"sr" : @[ @"sr_BA", @"sr_ME", @"sr_RS", @"sr_Latn_BA", @"sr_Latn_ME", @"sr_Latn_RS" ], + // European Spanish + @"es_ES" : @[ @"es", @"es_ES", @"es-ES" ], + // Mexican Spanish + @"es_MX" : @[ @"es-MX", @"es_MX", @"es_US", @"es-US" ], + // Latin American Spanish + @"es_419" : @[ + @"es_AR", @"es_BO", @"es_CL", @"es_CO", @"es_CR", @"es_DO", @"es_EC", + @"es_SV", @"es_GT", @"es_HN", @"es_NI", @"es_PA", @"es_PY", @"es_PE", + @"es_PR", @"es_UY", @"es_VE", @"es-AR", @"es-CL", @"es-CO" + ], + // Thai + @"th" : @[ @"th", @"th_TH", @"th_TH_TH" ], + }; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingAnalytics.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingAnalytics.h new file mode 100644 index 00000000..92eeb054 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingAnalytics.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides integration between FIRMessaging and Analytics. + * + * All Analytics dependencies should be kept in this class, and missing dependencies should be + * handled gracefully. + * + */ +@interface FIRMessagingAnalytics : NSObject + +/** + * Determine whether a notification has the properties to be loggable to Analytics. + * If so, send the notification. + * @param notification The notification payload from APNs + * @param analytics The class to be used as the receiver of the logging method + */ + ++ (void)logMessage:(NSDictionary *)notification + toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingAnalytics.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingAnalytics.m new file mode 100644 index 00000000..185e683b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingAnalytics.m @@ -0,0 +1,222 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingAnalytics.h" + +#import "GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h" +#import "GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h" +#import "Interop/Analytics/Public/FIRInteropEventNames.h" +#import "Interop/Analytics/Public/FIRInteropParameterNames.h" + +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" + +static NSString *const kLogTag = @"FIRMessagingAnalytics"; + +// aps Key +static NSString *const kApsKey = @"aps"; +static NSString *const kApsAlertKey = @"alert"; +static NSString *const kApsSoundKey = @"sound"; +static NSString *const kApsBadgeKey = @"badge"; +static NSString *const kApsContentAvailableKey = @"badge"; + +// Data Key +static NSString *const kDataKey = @"data"; + +// Messaging From Key +static NSString *const kFIRMessagingFromKey = @"from"; + +static NSString *const kFIRParameterLabel = @"label"; + +static NSString *const kReengagementSource = @"Firebase"; +static NSString *const kReengagementMedium = @"notification"; + +// Analytics +static NSString *const kAnalyticsEnabled = @"google.c.a." + @"e"; +static NSString *const kAnalyticsComposerIdentifier = @"google.c.a." + @"c_id"; +static NSString *const kAnalyticsComposerLabel = @"google.c.a." + @"c_l"; +static NSString *const kAnalyticsMessageLabel = @"google.c.a." + @"m_l"; +static NSString *const kAnalyticsMessageTimestamp = @"google.c.a." + @"ts"; +static NSString *const kAnalyticsMessageUseDeviceTime = @"google.c.a." + @"udt"; +static NSString *const kAnalyticsTrackConversions = @"google.c.a." + @"tc"; + +@implementation FIRMessagingAnalytics + ++ (BOOL)canLogNotification:(NSDictionary *)notification { + if (!notification.count) { + // Payload is empty + return NO; + } + NSString *isAnalyticsLoggingEnabled = notification[kAnalyticsEnabled]; + if (![isAnalyticsLoggingEnabled isKindOfClass:[NSString class]] || + ![isAnalyticsLoggingEnabled isEqualToString:@"1"]) { + // Analytics logging is not enabled + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics001, + @"Analytics logging is disabled. Do not log event."); + return NO; + } + return YES; +} + ++ (void)logOpenNotification:(NSDictionary *)notification + toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics { + [self logUserPropertyForConversionTracking:notification toAnalytics:analytics]; + [self logEvent:kFIRIEventNotificationOpen withNotification:notification toAnalytics:analytics]; +} + ++ (void)logForegroundNotification:(NSDictionary *)notification + toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics { + [self logEvent:kFIRIEventNotificationForeground + withNotification:notification + toAnalytics:analytics]; +} + ++ (void)logEvent:(NSString *)event + withNotification:(NSDictionary *)notification + toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics { + if (!event.length) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalyticsInvalidEvent, + @"Can't log analytics with empty event."); + return; + } + NSMutableDictionary *params = [self paramsForEvent:event withNotification:notification]; + + [analytics logEventWithOrigin:@"fcm" name:event parameters:params]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics005, @"%@: Sending event: %@ params: %@", + kLogTag, event, params); +} + ++ (NSMutableDictionary *)paramsForEvent:(NSString *)event + withNotification:(NSDictionary *)notification { + NSDictionary *analyticsDataMap = notification; + if (!analyticsDataMap.count) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics000, + @"No data found in notification. Will not log any analytics events."); + return nil; + } + + if (![self canLogNotification:analyticsDataMap]) { + return nil; + } + + NSMutableDictionary *params = [NSMutableDictionary dictionary]; + NSString *composerIdentifier = analyticsDataMap[kAnalyticsComposerIdentifier]; + if ([composerIdentifier isKindOfClass:[NSString class]] && composerIdentifier.length) { + params[kFIRIParameterMessageIdentifier] = [composerIdentifier copy]; + } + + NSString *composerLabel = analyticsDataMap[kAnalyticsComposerLabel]; + if ([composerLabel isKindOfClass:[NSString class]] && composerLabel.length) { + params[kFIRIParameterMessageName] = [composerLabel copy]; + } + + NSString *messageLabel = analyticsDataMap[kAnalyticsMessageLabel]; + if ([messageLabel isKindOfClass:[NSString class]] && messageLabel.length) { + params[kFIRParameterLabel] = [messageLabel copy]; + } + + NSString *from = analyticsDataMap[kFIRMessagingFromKey]; + if ([from isKindOfClass:[NSString class]] && [from containsString:@"/topics/"]) { + params[kFIRIParameterTopic] = [from copy]; + } + + id timestamp = analyticsDataMap[kAnalyticsMessageTimestamp]; + if ([timestamp respondsToSelector:@selector(longLongValue)]) { + int64_t timestampValue = [timestamp longLongValue]; + if (timestampValue != 0) { + params[kFIRIParameterMessageTime] = @(timestampValue); + } + } + + if (analyticsDataMap[kAnalyticsMessageUseDeviceTime]) { + params[kFIRIParameterMessageDeviceTime] = analyticsDataMap[kAnalyticsMessageUseDeviceTime]; + } + + return params; +} + ++ (void)logUserPropertyForConversionTracking:(NSDictionary *)notification + toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics { + NSInteger shouldTrackConversions = [notification[kAnalyticsTrackConversions] integerValue]; + if (shouldTrackConversions != 1) { + return; + } + + NSString *composerIdentifier = notification[kAnalyticsComposerIdentifier]; + if ([composerIdentifier isKindOfClass:[NSString class]] && composerIdentifier.length) { + // Set user property for event. + [analytics setUserPropertyWithOrigin:@"fcm" + name:kFIRIUserPropertyLastNotification + value:composerIdentifier]; + + // Set the re-engagement attribution properties. + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:3]; + params[kFIRIParameterSource] = kReengagementSource; + params[kFIRIParameterMedium] = kReengagementMedium; + params[kFIRIParameterCampaign] = composerIdentifier; + [analytics logEventWithOrigin:@"fcm" name:kFIRIEventFirebaseCampaign parameters:params]; + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics003, + @"%@: Sending event: %@ params: %@", kLogTag, + kFIRIEventFirebaseCampaign, params); + + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeAnalytics004, + @"%@: Failed to set user property: %@ value: %@", kLogTag, + kFIRIUserPropertyLastNotification, composerIdentifier); + } +} + ++ (void)logMessage:(NSDictionary *)notification + toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics { + // iOS onlly because Analytics doesn't support tvOS. +#if TARGET_OS_IOS + if (![self canLogNotification:notification]) { + return; + } + + UIApplication *application = [GULAppDelegateSwizzler sharedApplication]; + if (!application) { + return; + } + UIApplicationState applicationState = application.applicationState; + switch (applicationState) { + case UIApplicationStateInactive: + // App was either in background(suspended) or inactive and user tapped on a display + // notification. + [self logOpenNotification:notification toAnalytics:analytics]; + break; + + case UIApplicationStateActive: + // App was in foreground when it received the notification. + [self logForegroundNotification:notification toAnalytics:analytics]; + break; + + default: + // Only a silent notification (i.e. 'content-available' is true) can be received while the app + // is in the background. These messages aren't loggable anyway. + break; + } +#endif +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingClient.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingClient.h new file mode 100644 index 00000000..b7208ddd --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingClient.h @@ -0,0 +1,156 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessaging.h> + +@class GULReachabilityChecker; +@class GPBMessage; + +@class FIRMessagingConnection; +@class FIRMessagingDataMessageManager; +@class FIRMessagingRmqManager; + +/** + * Callback to handle MCS connection requests. + * + * @param error The error object if any while trying to connect with MCS else nil. + */ +typedef void (^FIRMessagingConnectCompletionHandler)(NSError *error); + +@protocol FIRMessagingClientDelegate <NSObject> + +@end + +/** + * The client handles the subscribe/unsubscribe for an unregistered senderID + * and device. It also manages the FIRMessaging data connection, the exponential backoff + * algorithm in case of registration failures, sign in failures and unregister + * failures. It also handles the reconnect logic if the FIRMessaging connection is + * broken off by some error during an active session. + */ +@interface FIRMessagingClient : NSObject + +@property(nonatomic, readonly, strong) FIRMessagingConnection *connection; +@property(nonatomic, readwrite, weak) FIRMessagingDataMessageManager *dataMessageManager; + +// Designated initializer +- (instancetype)initWithDelegate:(id<FIRMessagingClientDelegate>)delegate + reachability:(GULReachabilityChecker *)reachability + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager; + +- (void)teardown; + +- (void)cancelAllRequests; + +#pragma mark - FIRMessaging subscribe + +/** + * Update the subscription associated with the given token and topic. + * + * For a to-be-created subscription we check if the client is already + * subscribed to the topic or not. If subscribed we should have the + * subscriptionID in the cache and we return from there itself, else we call + * the FIRMessaging backend to create a new subscription for the topic for this client. + * + * For delete subscription requests we delete the stored subscription in the + * client and then invoke the FIRMessaging backend to delete the existing subscription + * completely. + * + * @param token The token associated with the device. + * @param topic The topic for which the subscription should be updated. + * @param options The options to be passed in to the subscription request. + * @param shouldDelete If YES this would delete the subscription from the cache + * and also let the FIRMessaging backend know that we need to delete + * the subscriptionID associated with this topic. + * If NO we try to create a new subscription for the given + * token and topic. + * @param handler The handler to invoke once the subscription request + * finishes. + */ +- (void)updateSubscriptionWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler; + +#pragma mark - MCS Connection + +/** + * Create a MCS connection. + * + * @param handler The handler to be invokend once the connection is setup. If + * setting up the connection fails we invoke the handler with + * an appropriate error object. + */ +- (void)connectWithHandler:(FIRMessagingConnectCompletionHandler)handler; + +/** + * Disconnect the current MCS connection. If there is no valid connection this + * should be a NO-OP. + */ +- (void)disconnect; + +#pragma mark - MCS Connection State + +/** + * If we are connected to MCS or not. This doesn't take into account the fact if + * the client has been signed in(verified) by MCS. + * + * @return YES if we are signed in or connecting and trying to sign-in else NO. + */ +@property(nonatomic, readonly) BOOL isConnected; + +/** + * If we have an active MCS connection + * + * @return YES if we have an active MCS connection else NO. + */ +@property(nonatomic, readonly) BOOL isConnectionActive; + +/** + * If we should be connected to MCS + * + * @return YES if we have attempted a connection and not requested to disconect. + */ +@property(nonatomic, readonly) BOOL shouldStayConnected; + +/** + * Schedule a retry to connect to MCS. If `immediately` is `YES` try to + * schedule a retry now else retry with some delay. + * + * @param immediately Should retry right now. + */ +- (void)retryConnectionImmediately:(BOOL)immediately; + +#pragma mark - Messages + +/** + * Send a message over the MCS connection. + * + * @param message Message to be sent. + */ +- (void)sendMessage:(GPBMessage *)message; + +/** + * Send message if we have an active MCS connection. If not cache the message + * for this session and in case we are able to re-establish the connection try + * again else drop it. This should only be used for TTL=0 messages for now. + * + * @param message Message to be sent. + */ +- (void)sendOnConnectOrDrop:(GPBMessage *)message; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingClient.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingClient.m new file mode 100644 index 00000000..315248b7 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingClient.m @@ -0,0 +1,518 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingClient.h" + +#import "FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h" + +#import <FirebaseInstanceID/FIRInstanceID_Private.h> +#import <FirebaseMessaging/FIRMessaging.h> +#import "GoogleUtilities/Reachability/Private/GULReachabilityChecker.h" + +#import "FirebaseMessaging/Sources/FIRMessagingConnection.h" +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" +#import "FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.h" +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" + +static const NSTimeInterval kConnectTimeoutInterval = 40.0; +static const NSTimeInterval kReconnectDelayInSeconds = 2 * 60; // 2 minutes + +static const NSUInteger kMaxRetryExponent = 10; // 2^10 = 1024 seconds ~= 17 minutes + +static NSString *const kFIRMessagingMCSServerHost = @"mtalk.google.com"; +static NSUInteger const kFIRMessagingMCSServerPort = 5228; + +// register device with checkin +typedef void (^FIRMessagingRegisterDeviceHandler)(NSError *error); + +static NSString *FIRMessagingServerHost() { + static NSString *serverHost = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHostAndPort = environment[@"FCM_MCS_HOST"]; + NSString *host = [customServerHostAndPort componentsSeparatedByString:@":"].firstObject; + if (host) { + serverHost = host; + } else { + serverHost = kFIRMessagingMCSServerHost; + } + }); + return serverHost; +} + +static NSUInteger FIRMessagingServerPort() { + static NSUInteger serverPort = kFIRMessagingMCSServerPort; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHostAndPort = environment[@"FCM_MCS_HOST"]; + NSArray<NSString *> *components = [customServerHostAndPort componentsSeparatedByString:@":"]; + NSUInteger port = (NSUInteger)[components.lastObject integerValue]; + if (port != 0) { + serverPort = port; + } + }); + return serverPort; +} + +@interface FIRMessagingClient () <FIRMessagingConnectionDelegate> + +@property(nonatomic, readwrite, weak) id<FIRMessagingClientDelegate> clientDelegate; +@property(nonatomic, readwrite, strong) FIRMessagingConnection *connection; +@property(nonatomic, readonly, strong) FIRMessagingPubSubRegistrar *registrar; +@property(nonatomic, readwrite, strong) NSString *senderId; + +// FIRMessagingService owns these instances +@property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, weak) GULReachabilityChecker *reachability; + +@property(nonatomic, readwrite, assign) int64_t lastConnectedTimestamp; +@property(nonatomic, readwrite, assign) int64_t lastDisconnectedTimestamp; +@property(nonatomic, readwrite, assign) NSUInteger connectRetryCount; + +// Should we stay connected to MCS or not. Should be YES throughout the lifetime +// of a MCS connection. If set to NO it signifies that an existing MCS connection +// should be disconnected. +@property(nonatomic, readwrite, assign) BOOL stayConnected; +@property(nonatomic, readwrite, assign) NSTimeInterval connectionTimeoutInterval; + +// Used if the MCS connection suddenly breaksdown in the middle and we want to reconnect +// with some permissible delay we schedule a reconnect and set it to YES and when it's +// scheduled this will be set back to NO. +@property(nonatomic, readwrite, assign) BOOL didScheduleReconnect; + +// handlers +@property(nonatomic, readwrite, copy) FIRMessagingConnectCompletionHandler connectHandler; + +@end + +@implementation FIRMessagingClient + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithDelegate:(id<FIRMessagingClientDelegate>)delegate + reachability:(GULReachabilityChecker *)reachability + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager { + self = [super init]; + if (self) { + _reachability = reachability; + _clientDelegate = delegate; + _rmq2Manager = rmq2Manager; + _registrar = [[FIRMessagingPubSubRegistrar alloc] init]; + _connectionTimeoutInterval = kConnectTimeoutInterval; + // Listen for checkin fetch notifications, as connecting to MCS may have failed due to + // missing checkin info (while it was being fetched). + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(checkinFetched:) + name:kFIRMessagingCheckinFetchedNotification + object:nil]; + } + return self; +} + +- (void)teardown { + if (![NSThread isMainThread]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient000, + @"FIRMessagingClient should be called from main thread only."); + } + self.stayConnected = NO; + + // Clear all the handlers + self.connectHandler = nil; + + [self.connection teardown]; + + // Stop all subscription requests + [self.registrar stopAllSubscriptionRequests]; + + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)cancelAllRequests { + // Stop any checkin requests or any subscription requests + [self.registrar stopAllSubscriptionRequests]; + + // Stop any future connection requests to MCS + if (self.stayConnected && self.isConnected && !self.isConnectionActive) { + self.stayConnected = NO; + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + } +} + +#pragma mark - FIRMessaging subscribe + +- (void)updateSubscriptionWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler { + FIRMessagingTopicOperationCompletion completion = ^void(NSError *error) { + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeClient001, @"Failed to subscribe to topic %@", + error); + } else { + if (shouldDelete) { + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeClient002, + @"Successfully unsubscribed from topic %@", topic); + } else { + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeClient003, + @"Successfully subscribed to topic %@", topic); + } + } + if (handler) { + handler(error); + } + }; + + if ([[FIRInstanceID instanceID] tryToLoadValidCheckinInfo]) { + [self.registrar updateSubscriptionToTopic:topic + withToken:token + options:options + shouldDelete:shouldDelete + handler:completion]; + } else { + NSString *failureReason = @"Device ID and checkin info is not found. Will not proceed with " + @"subscription/unsubscription."; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRegistrar000, @"%@", failureReason); + NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeMissingDeviceID + failureReason:failureReason]; + handler(error); + } +} + +#pragma mark - MCS Connection + +- (BOOL)isConnected { + return self.stayConnected && self.connection.state != kFIRMessagingConnectionNotConnected; +} + +- (BOOL)isConnectionActive { + return self.stayConnected && self.connection.state == kFIRMessagingConnectionSignedIn; +} + +- (BOOL)shouldStayConnected { + return self.stayConnected; +} + +- (void)retryConnectionImmediately:(BOOL)immediately { + // Do not connect to an invalid host or an invalid port + if (!self.stayConnected || !self.connection.host || self.connection.port == 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient004, + @"FIRMessaging connection will not reconnect to MCS. " + @"Stay connected: %d", + self.stayConnected); + return; + } + if (self.isConnectionActive) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient005, + @"FIRMessaging Connection skip retry, active"); + // already connected and logged in. + // Heartbeat alarm is set and will force close the connection + return; + } + if (self.isConnected) { + // already connected and logged in. + // Heartbeat alarm is set and will force close the connection + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient006, + @"FIRMessaging Connection skip retry, connected"); + return; + } + + if (immediately) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient007, + @"Try to connect to MCS immediately"); + [self tryToConnect]; + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient008, @"Try to connect to MCS lazily"); + // Avoid all the other logic that we have in other clients, since this would always happen + // when the app is in the foreground and since the FIRMessaging connection isn't shared with any + // other app we can be more aggressive in reconnections + if (!self.didScheduleReconnect) { + FIRMessaging_WEAKIFY(self); + dispatch_after( + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kReconnectDelayInSeconds * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + FIRMessaging_STRONGIFY(self); + self.didScheduleReconnect = NO; + [self tryToConnect]; + }); + + self.didScheduleReconnect = YES; + } + } +} + +- (void)connectWithHandler:(FIRMessagingConnectCompletionHandler)handler { + if (self.isConnected) { + NSError *error = + [NSError messagingErrorWithCode:kFIRMessagingErrorCodeAlreadyConnected + failureReason: + @"FIRMessaging is already connected. Will not try to connect again."]; + handler(error); + return; + } + self.lastDisconnectedTimestamp = FIRMessagingCurrentTimestampInMilliseconds(); + self.connectHandler = handler; + [self connect]; +} + +- (void)connect { + // reset retry counts + self.connectRetryCount = 0; + + if (self.isConnected) { + return; + } + + self.stayConnected = YES; + if (![[FIRInstanceID instanceID] tryToLoadValidCheckinInfo]) { + // Checkin info is not available. This may be due to the checkin still being fetched. + NSString *failureReason = @"Failed to connect to MCS. No deviceID and secret found."; + if (self.connectHandler) { + NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeMissingDeviceID + failureReason:failureReason]; + self.connectHandler(error); + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient009, @"%@", failureReason); + // Return for now. If checkin is, in fact, retrieved, the + // |kFIRMessagingCheckinFetchedNotification| will be fired. + return; + } + [self setupConnectionAndConnect]; +} + +- (void)disconnect { + // user called disconnect + // We don't want to connect later even if no network is available. + [self disconnectWithTryToConnectLater:NO]; +} + +/** + * Disconnect the current client connection. Also explicitly stop and connction retries. + * + * @param tryToConnectLater If YES will try to connect later when sending upstream messages + * else if NO do not connect again until user explicitly calls + * connect. + */ +- (void)disconnectWithTryToConnectLater:(BOOL)tryToConnectLater { + self.stayConnected = tryToConnectLater; + [self.connection signOut]; + + // since we can disconnect while still trying to establish the connection it's required to + // cancel all performSelectors else the object might be retained + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(tryToConnect) + object:nil]; + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(didConnectTimeout) + object:nil]; + self.connectHandler = nil; +} + +#pragma mark - Checkin Notification +- (void)checkinFetched:(NSNotification *)notification { + // A failed checkin may have been the reason for the connection failure. Attempt a connection + // if the checkin fetched notification is fired. + if (self.stayConnected && !self.isConnected) { + [self connect]; + } +} + +#pragma mark - Messages + +- (void)sendMessage:(GPBMessage *)message { + [self.connection sendProto:message]; +} + +- (void)sendOnConnectOrDrop:(GPBMessage *)message { + [self.connection sendOnConnectOrDrop:message]; +} + +#pragma mark - FIRMessagingConnectionDelegate + +- (void)connection:(FIRMessagingConnection *)fcmConnection + didCloseForReason:(FIRMessagingConnectionCloseReason)reason { + self.lastDisconnectedTimestamp = FIRMessagingCurrentTimestampInMilliseconds(); + + if (reason == kFIRMessagingConnectionCloseReasonSocketDisconnected) { + // Cancel the not-yet-triggered timeout task before rescheduling, in case the previous sign in + // failed, due to a connection error caused by bad network. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(didConnectTimeout) + object:nil]; + } + if (self.stayConnected) { + [self scheduleConnectRetry]; + } +} + +- (void)didLoginWithConnection:(FIRMessagingConnection *)fcmConnection { + // Cancel the not-yet-triggered timeout task. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(didConnectTimeout) + object:nil]; + self.connectRetryCount = 0; + self.lastConnectedTimestamp = FIRMessagingCurrentTimestampInMilliseconds(); + + [self.dataMessageManager setDeviceAuthID:[FIRInstanceID instanceID].deviceAuthID + secretToken:[FIRInstanceID instanceID].secretToken]; + if (self.connectHandler) { + self.connectHandler(nil); + // notified the third party app with the registrationId. + // we don't want them to know about the connection status and how it changes + // so remove this handler + self.connectHandler = nil; + } +} + +- (void)connectionDidRecieveMessage:(GtalkDataMessageStanza *)message { + NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message]; + if ([parsedMessage count]) { + [self.dataMessageManager didReceiveParsedMessage:parsedMessage]; + } +} + +- (void)connectionDidReceiveAckForRmqIds:(NSArray *)rmqIds { + NSSet *rmqIDSet = [NSSet setWithArray:rmqIds]; + NSMutableArray *messagesSent = [NSMutableArray arrayWithCapacity:rmqIds.count]; + [self.rmq2Manager scanWithRmqMessageHandler:^(NSDictionary *messages) { + for (NSString *rmqID in messages) { + GPBMessage *proto = messages[rmqID]; + GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)proto; + if ([rmqIDSet containsObject:rmqID]) { + [messagesSent addObject:stanza]; + } + } + }]; + for (GtalkDataMessageStanza *message in messagesSent) { + [self.dataMessageManager didSendDataMessageStanza:message]; + } + [self.rmq2Manager removeRmqMessagesWithRmqIds:rmqIds]; +} + +#pragma mark - Private + +- (void)setupConnectionAndConnect { + [self setupConnection]; + [self tryToConnect]; +} + +- (void)setupConnection { + NSString *host = FIRMessagingServerHost(); + NSUInteger port = FIRMessagingServerPort(); + if (self.connection != nil) { + // if there is an old connection, explicitly sign it off. + [self.connection signOut]; + self.connection.delegate = nil; + } + self.connection = + [[FIRMessagingConnection alloc] initWithAuthID:[FIRInstanceID instanceID].deviceAuthID + token:[FIRInstanceID instanceID].secretToken + host:host + port:port + runLoop:[NSRunLoop mainRunLoop] + rmq2Manager:self.rmq2Manager + fcmManager:self.dataMessageManager]; + self.connection.delegate = self; +} + +- (void)tryToConnect { + if (!self.stayConnected) { + return; + } + + // Cancel any other pending signin requests. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(tryToConnect) + object:nil]; + NSString *deviceAuthID = [FIRInstanceID instanceID].deviceAuthID; + NSString *secretToken = [FIRInstanceID instanceID].secretToken; + if (deviceAuthID.length == 0 || secretToken.length == 0 || !self.connection) { + FIRMessagingLoggerWarn( + kFIRMessagingMessageCodeClientInvalidState, + @"Invalid state to connect, deviceAuthID: %@, secretToken: %@, connection state: %ld", + deviceAuthID, secretToken, (long)self.connection.state); + return; + } + // Do not re-sign in if there is already a connection in progress. + if (self.connection.state != kFIRMessagingConnectionNotConnected) { + return; + } + + self.connectRetryCount = MIN(kMaxRetryExponent, self.connectRetryCount + 1); + [self performSelector:@selector(didConnectTimeout) + withObject:nil + afterDelay:self.connectionTimeoutInterval]; + [self.connection signIn]; +} + +- (void)didConnectTimeout { + if (self.connection.state == kFIRMessagingConnectionSignedIn) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeClientInvalidStateTimeout, + @"Invalid state for connection timeout."); + } + if (self.stayConnected) { + [self.connection signOut]; + [self scheduleConnectRetry]; + } +} + +#pragma mark - Schedulers + +- (void)scheduleConnectRetry { + GULReachabilityStatus status = self.reachability.reachabilityStatus; + BOOL isReachable = (status == kGULReachabilityViaWifi || status == kGULReachabilityViaCellular); + if (!isReachable) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient010, + @"Internet not reachable when signing into MCS during a retry"); + + FIRMessagingConnectCompletionHandler handler = [self.connectHandler copy]; + // disconnect before issuing a callback + [self disconnectWithTryToConnectLater:YES]; + NSError *error = + [NSError messagingErrorWithCode:kFIRMessagingErrorCodeNetwork + failureReason:@"No internet available, cannot connect to FIRMessaging"]; + if (handler) { + handler(error); + self.connectHandler = nil; + } + return; + } + + NSUInteger retryInterval = [self nextRetryInterval]; + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient011, + @"Failed to sign in to MCS, retry in %lu seconds", + _FIRMessaging_UL(retryInterval)); + [self performSelector:@selector(tryToConnect) withObject:nil afterDelay:retryInterval]; +} + +- (NSUInteger)nextRetryInterval { + return 1u << self.connectRetryCount; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingCodedInputStream.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingCodedInputStream.h new file mode 100644 index 00000000..8f22290c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingCodedInputStream.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@interface FIRMessagingCodedInputStream : NSObject + +@property(nonatomic, readonly, assign) size_t offset; + +- (instancetype)initWithData:(NSData *)data; +- (BOOL)readTag:(int8_t *)tag; +- (BOOL)readLength:(int32_t *)length; +- (NSData *)readDataWithLength:(uint32_t)length; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingCodedInputStream.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingCodedInputStream.m new file mode 100644 index 00000000..b96c01e2 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingCodedInputStream.m @@ -0,0 +1,148 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingCodedInputStream.h" + +#import "FirebaseMessaging/Sources/FIRMMessageCode.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" + +typedef struct { + const void *bytes; + size_t bufferSize; + size_t bufferPos; +} BufferState; + +static BOOL CheckSize(BufferState *state, size_t size) { + size_t newSize = state->bufferPos + size; + if (newSize > state->bufferSize) { + return NO; + } + return YES; +} + +static BOOL ReadRawByte(BufferState *state, int8_t *output) { + if (state == NULL || output == NULL) { + FIRMessagingLoggerDebug(kFIRMessagingCodeInputStreamInvalidParameters, @"Invalid parameters."); + } + if (output != nil && CheckSize(state, sizeof(int8_t))) { + *output = ((int8_t *)state->bytes)[state->bufferPos++]; + return YES; + } + return NO; +} + +static BOOL ReadRawVarInt32(BufferState *state, int32_t *output) { + if (state == NULL || output == NULL) { + FIRMessagingLoggerDebug(kFIRMessagingCodeInputStreamInvalidParameters, @"Invalid parameters."); + return NO; + } + int8_t tmp = 0; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + *output = tmp; + return YES; + } + int32_t result = tmp & 0x7f; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + result |= tmp << 7; + } else { + result |= (tmp & 0x7f) << 7; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + result |= tmp << 14; + } else { + result |= (tmp & 0x7f) << 14; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + result |= tmp << 21; + } else { + result |= (tmp & 0x7f) << 21; + if (!ReadRawByte(state, &tmp)) { + return NO; + } + result |= tmp << 28; + if (tmp < 0) { + // Discard upper 32 bits. + for (int i = 0; i < 5; ++i) { + if (!ReadRawByte(state, &tmp)) { + return NO; + } + if (tmp >= 0) { + *output = result; + return YES; + } + } + return NO; + } + } + } + } + *output = result; + return YES; +} + +@interface FIRMessagingCodedInputStream () + +@property(nonatomic, readwrite, strong) NSData *buffer; +@property(nonatomic, readwrite, assign) BufferState state; + +@end + +@implementation FIRMessagingCodedInputStream +; + +- (instancetype)initWithData:(NSData *)data { + self = [super init]; + if (self) { + _buffer = data; + _state.bytes = _buffer.bytes; + _state.bufferSize = _buffer.length; + } + return self; +} + +- (size_t)offset { + return _state.bufferPos; +} + +- (BOOL)readTag:(int8_t *)tag { + return ReadRawByte(&_state, tag); +} + +- (BOOL)readLength:(int32_t *)length { + return ReadRawVarInt32(&_state, length); +} + +- (NSData *)readDataWithLength:(uint32_t)length { + if (!CheckSize(&_state, length)) { + return nil; + } + const void *bytesToRead = _state.bytes + _state.bufferPos; + NSData *result = [NSData dataWithBytes:bytesToRead length:length]; + _state.bufferPos += length; + return result; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConnection.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConnection.h new file mode 100644 index 00000000..34cb2940 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConnection.h @@ -0,0 +1,104 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class FIRMessagingConnection; +@class FIRMessagingDataMessageManager; +@class FIRMessagingRmqManager; + +@class GtalkDataMessageStanza; +@class GPBMessage; + +typedef void (^FIRMessagingMessageHandler)(NSDictionary *); + +typedef NS_ENUM(NSUInteger, FIRMessagingConnectionState) { + kFIRMessagingConnectionNotConnected = 0, + kFIRMessagingConnectionConnecting, + kFIRMessagingConnectionConnected, + kFIRMessagingConnectionSignedIn, +}; + +typedef NS_ENUM(NSUInteger, FIRMessagingConnectionCloseReason) { + kFIRMessagingConnectionCloseReasonSocketDisconnected = 0, + kFIRMessagingConnectionCloseReasonTimeout, + kFIRMessagingConnectionCloseReasonUserDisconnect, +}; + +@protocol FIRMessagingConnectionDelegate <NSObject> + +- (void)connection:(FIRMessagingConnection *)fcmConnection + didCloseForReason:(FIRMessagingConnectionCloseReason)reason; +- (void)didLoginWithConnection:(FIRMessagingConnection *)fcmConnection; +- (void)connectionDidRecieveMessage:(GtalkDataMessageStanza *)message; +/** + * Called when a stream ACK or a selective ACK are received - this indicates the + * message has been received by MCS. + */ +- (void)connectionDidReceiveAckForRmqIds:(NSArray *)rmqIds; + +@end + +/** + * This class maintains the actual FIRMessaging connection that we use to receive and send messages + * while the app is in foreground. Once we have a registrationID from the FIRMessaging backend we + * are able to set up this connection which is used for any further communication with FIRMessaging + * backend. In case the connection breaks off while the app is still being used we try to rebuild + * the connection with an exponential backoff. + * + * This class also notifies the delegate about the main events happening in the lifcycle of the + * FIRMessaging connection (read FIRMessagingConnectionDelegate). All of the `on-the-wire` + * interactions with FIRMessaging are channelled through here. + */ +@interface FIRMessagingConnection : NSObject + +@property(nonatomic, readonly, assign) FIRMessagingConnectionState state; +@property(nonatomic, readonly, copy) NSString *host; +@property(nonatomic, readonly, assign) NSUInteger port; +@property(nonatomic, readwrite, weak) id<FIRMessagingConnectionDelegate> delegate; + +- (instancetype)initWithAuthID:(NSString *)authId + token:(NSString *)token + host:(NSString *)host + port:(NSUInteger)port + runLoop:(NSRunLoop *)runLoop + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + fcmManager:(FIRMessagingDataMessageManager *)dataMessageManager; + +- (void)signIn; // connect +- (void)signOut; // disconnect + +/** + * Teardown the FIRMessaging connection and deallocate the resources being held up by the + * connection. + */ +- (void)teardown; + +/** + * Send proto to the wire. The message will be cached before we try to send so that in case of + * failure we can send it again later on when we have connection. + */ +- (void)sendProto:(GPBMessage *)proto; + +/** + * Send a message after the currently in progress connection succeeds, otherwise drop it. + * + * This should be used for TTL=0 messages that force a reconnect. They shouldn't be persisted + * in the RMQ, but they should be sent if the reconnect is successful. + */ +- (void)sendOnConnectOrDrop:(GPBMessage *)message; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConnection.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConnection.m new file mode 100644 index 00000000..600c5906 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConnection.m @@ -0,0 +1,683 @@ +/* + * Copyright 2020 Google LLC + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingConnection.h" + +#import <FirebaseMessaging/FIRMessaging.h> + +#import "FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h" +#import "FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingSecureSocket.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessagingVersionUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" + +static NSInteger const kIqSelectiveAck = 12; +static NSInteger const kIqStreamAck = 13; +static int const kInvalidStreamId = -1; + +static NSTimeInterval const kHeartbeatInterval = 30.0; +static NSTimeInterval const kConnectionTimeout = 20.0; +static int32_t const kAckingInterval = 10; + +static NSString *const kUnackedS2dIdKey = @"FIRMessagingUnackedS2dIdKey"; +static NSString *const kAckedS2dIdMapKey = @"FIRMessagingAckedS2dIdMapKey"; + +static NSString *const kRemoteFromAddress = @"from"; + +@interface FIRMessagingD2SInfo : NSObject + +@property(nonatomic, readwrite, assign) int streamId; +@property(nonatomic, readwrite, strong) NSString *d2sID; +- (instancetype)initWithStreamId:(int)streamId d2sId:(NSString *)d2sID; + +@end + +@implementation FIRMessagingD2SInfo + +- (instancetype)initWithStreamId:(int)streamId d2sId:(NSString *)d2sID { + self = [super init]; + if (self) { + _streamId = streamId; + _d2sID = [d2sID copy]; + } + return self; +} + +- (BOOL)isEqual:(id)object { + if ([object isKindOfClass:[self class]]) { + FIRMessagingD2SInfo *other = (FIRMessagingD2SInfo *)object; + return self.streamId == other.streamId && [self.d2sID isEqualToString:other.d2sID]; + } + return NO; +} + +- (NSUInteger)hash { + return [self.d2sID hash]; +} + +@end + +@interface FIRMessagingConnection () <FIRMessagingSecureSocketDelegate> + +@property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, weak) FIRMessagingDataMessageManager *dataMessageManager; + +@property(nonatomic, readwrite, assign) FIRMessagingConnectionState state; +@property(nonatomic, readwrite, copy) NSString *host; +@property(nonatomic, readwrite, assign) NSUInteger port; + +@property(nonatomic, readwrite, strong) NSString *authId; +@property(nonatomic, readwrite, strong) NSString *token; + +@property(nonatomic, readwrite, strong) FIRMessagingSecureSocket *socket; + +@property(nonatomic, readwrite, assign) int64_t lastLoginServerTimestamp; +@property(nonatomic, readwrite, assign) int lastStreamIdAcked; +@property(nonatomic, readwrite, assign) int inStreamId; +@property(nonatomic, readwrite, assign) int outStreamId; + +@property(nonatomic, readwrite, strong) NSMutableArray *unackedS2dIds; +@property(nonatomic, readwrite, strong) NSMutableDictionary *ackedS2dMap; +@property(nonatomic, readwrite, strong) NSMutableArray *d2sInfos; +// ttl=0 messages that need to be sent as soon as we establish a connection +@property(nonatomic, readwrite, strong) NSMutableArray *sendOnConnectMessages; + +@property(nonatomic, readwrite, strong) NSRunLoop *runLoop; + +@end + +@implementation FIRMessagingConnection +; + +- (instancetype)initWithAuthID:(NSString *)authId + token:(NSString *)token + host:(NSString *)host + port:(NSUInteger)port + runLoop:(NSRunLoop *)runLoop + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + fcmManager:(FIRMessagingDataMessageManager *)dataMessageManager { + self = [super init]; + if (self) { + _authId = [authId copy]; + _token = [token copy]; + _host = [host copy]; + _port = port; + _runLoop = runLoop; + _rmq2Manager = rmq2Manager; + _dataMessageManager = dataMessageManager; + + _d2sInfos = [NSMutableArray array]; + + _unackedS2dIds = [NSMutableArray arrayWithArray:[_rmq2Manager unackedS2dRmqIds]]; + _ackedS2dMap = [NSMutableDictionary dictionary]; + _sendOnConnectMessages = [NSMutableArray array]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"host: %@, port: %lu, stream id in: %d, stream id out: %d", + self.host, _FIRMessaging_UL(self.port), self.inStreamId, + self.outStreamId]; +} + +- (void)signIn { + if (self.state != kFIRMessagingConnectionNotConnected) { + return; + } + + // break it up for testing + [self setupConnectionSocket]; + [self connectToSocket:self.socket]; +} + +- (void)setupConnectionSocket { + self.socket = [[FIRMessagingSecureSocket alloc] init]; + self.socket.delegate = self; +} + +- (void)connectToSocket:(FIRMessagingSecureSocket *)socket { + self.state = kFIRMessagingConnectionConnecting; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection000, + @"Start connecting to FIRMessaging service."); + [socket connectToHost:self.host port:self.port onRunLoop:self.runLoop]; +} + +- (void)signOut { + // Clear the list of messages to be sent on connect. This will only + // have messages in it if an error happened before receiving the LoginResponse. + [self.sendOnConnectMessages removeAllObjects]; + + if (self.state == kFIRMessagingConnectionSignedIn) { + [self sendClose]; + } + if (self.state != kFIRMessagingConnectionNotConnected) { + [self disconnect]; + } +} + +- (void)teardown { + if (self.state != kFIRMessagingConnectionNotConnected) { + [self disconnect]; + } +} + +#pragma mark - FIRMessagingSecureSocketDelegate + +- (void)secureSocketDidConnect:(FIRMessagingSecureSocket *)socket { + self.state = kFIRMessagingConnectionConnected; + self.lastStreamIdAcked = 0; + self.inStreamId = 0; + self.outStreamId = 0; + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection001, + @"Connected to FIRMessaging service."); + [self resetUnconfirmedAcks]; + [self sendLoginRequest:self.authId token:self.token]; +} + +- (void)didDisconnectWithSecureSocket:(FIRMessagingSecureSocket *)socket { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection002, + @"Secure socket disconnected from FIRMessaging service. %ld", + (long)self.socket.state); + [self disconnect]; + [self.delegate connection:self + didCloseForReason:kFIRMessagingConnectionCloseReasonSocketDisconnected]; +} + +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didReceiveData:(NSData *)data + withTag:(int8_t)tag { + if (tag < 0) { + // Invalid proto tag + return; + } + + Class klassForTag = FIRMessagingGetClassForTag((FIRMessagingProtoTag)tag); + if ([klassForTag isSubclassOfClass:[NSNull class]]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeConnection003, @"Invalid tag %d for proto", + tag); + return; + } + + GPBMessage *proto = [klassForTag parseFromData:data error:NULL]; + if (tag == kFIRMessagingProtoTagLoginResponse && self.state != kFIRMessagingConnectionConnected) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection004, + @"Should not receive generated message when the connection is not connected."); + return; + } else if (tag != kFIRMessagingProtoTagLoginResponse && + self.state != kFIRMessagingConnectionSignedIn) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection005, + @"Should not receive generated message when the connection is not signed in."); + return; + } + + // If traffic is received after a heartbeat it is safe to assume the connection is healthy. + [self cancelConnectionTimeoutTask]; + [self performSelector:@selector(sendHeartbeatPing) withObject:nil afterDelay:kHeartbeatInterval]; + + [self willProcessProto:proto]; + switch (tag) { + case kFIRMessagingProtoTagLoginResponse: + [self didReceiveLoginResponse:(GtalkLoginResponse *)proto]; + break; + case kFIRMessagingProtoTagDataMessageStanza: + [self didReceiveDataMessageStanza:(GtalkDataMessageStanza *)proto]; + break; + case kFIRMessagingProtoTagHeartbeatPing: + [self didReceiveHeartbeatPing:(GtalkHeartbeatPing *)proto]; + break; + case kFIRMessagingProtoTagHeartbeatAck: + [self didReceiveHeartbeatAck:(GtalkHeartbeatAck *)proto]; + break; + case kFIRMessagingProtoTagClose: + [self didReceiveClose:(GtalkClose *)proto]; + break; + case kFIRMessagingProtoTagIqStanza: + [self handleIqStanza:(GtalkIqStanza *)proto]; + break; + default: + [self didReceiveUnhandledProto:proto]; + break; + } +} + +// Called from secure socket once we have send the proto with given rmqId over the wire +// since we are mostly concerned with user facing messages which certainly have a rmqId +// we can retrieve them from the Rmq if necessary to look at stuff but for now we just +// log it. +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didSendProtoWithTag:(int8_t)tag + rmqId:(NSString *)rmqId { + // log the message + [self logMessage:rmqId messageType:tag isOut:YES]; +} + +#pragma mark - FIRMessagingTestConnection + +- (void)sendProto:(GPBMessage *)proto { + FIRMessagingProtoTag tag = FIRMessagingGetTagForProto(proto); + if (tag == kFIRMessagingProtoTagLoginRequest && self.state != kFIRMessagingConnectionConnected) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection006, + @"Cannot send generated message when the connection is not connected."); + return; + } else if (tag != kFIRMessagingProtoTagLoginRequest && + self.state != kFIRMessagingConnectionSignedIn) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection007, + @"Cannot send generated message when the connection is not signed in."); + return; + } + + if (self.socket == nil) { + return; + } + + [self willSendProto:proto]; + + [self.socket sendData:proto.data withTag:tag rmqId:FIRMessagingGetRmq2Id(proto)]; +} + +- (void)sendOnConnectOrDrop:(GPBMessage *)message { + if (self.state == kFIRMessagingConnectionSignedIn) { + // If a connection has already been established, send normally + [self sendProto:message]; + } else { + // Otherwise add them to the list of messages to send after login + [self.sendOnConnectMessages addObject:message]; + } +} + ++ (GtalkLoginRequest *)loginRequestWithToken:(NSString *)token authID:(NSString *)authID { + GtalkLoginRequest *login = [[GtalkLoginRequest alloc] init]; + login.accountId = 1000000; + login.authService = GtalkLoginRequest_AuthService_AndroidId; + login.authToken = token; + login.id_p = [NSString stringWithFormat:@"%@-%@", @"ios", FIRMessagingCurrentLibraryVersion()]; + login.domain = @"mcs.android.com"; + login.deviceId = [NSString stringWithFormat:@"android-%llx", authID.longLongValue]; + login.networkType = [self currentNetworkType]; + login.resource = authID; + login.user = authID; + login.useRmq2 = YES; + login.lastRmqId = 1; // Sending not enabled yet so this stays as 1. + return login; +} + ++ (int32_t)currentNetworkType { + // http://developer.android.com/reference/android/net/ConnectivityManager.html + int32_t fcmNetworkType; + FIRMessagingNetworkStatus type = [[FIRMessaging messaging] networkType]; + switch (type) { + case kFIRMessagingReachabilityReachableViaWiFi: + fcmNetworkType = 1; + break; + + case kFIRMessagingReachabilityReachableViaWWAN: + fcmNetworkType = 0; + break; + + default: + fcmNetworkType = -1; + break; + } + return fcmNetworkType; +} + +- (void)sendLoginRequest:(NSString *)authId token:(NSString *)token { + GtalkLoginRequest *login = [[self class] loginRequestWithToken:token authID:authId]; + + // clear the messages sent during last connection + if ([self.d2sInfos count]) { + [self.d2sInfos removeAllObjects]; + } + + if (self.unackedS2dIds.count > 0) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection008, + @"There are unacked persistent Ids in the login request: %@", + [self.unackedS2dIds.description stringByReplacingOccurrencesOfString:@"%" + withString:@"%%"]); + } + // Send out acks. + for (NSString *unackedPersistentS2dId in self.unackedS2dIds) { + [login.receivedPersistentIdArray addObject:unackedPersistentS2dId]; + } + + GtalkSetting *setting = [[GtalkSetting alloc] init]; + setting.name = @"new_vc"; + setting.value = @"1"; + [login.settingArray addObject:setting]; + + [self sendProto:login]; +} + +- (void)sendHeartbeatAck { + [self sendProto:[[GtalkHeartbeatAck alloc] init]]; +} + +- (void)sendHeartbeatPing { + // cancel the previous heartbeat request. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(sendHeartbeatPing) + object:nil]; + [self scheduleConnectionTimeoutTask]; + [self sendProto:[[GtalkHeartbeatPing alloc] init]]; +} + ++ (GtalkIqStanza *)createStreamAck { + GtalkIqStanza *iq = [[GtalkIqStanza alloc] init]; + iq.type = GtalkIqStanza_IqType_Set; + iq.id_p = @""; + GtalkExtension *ext = [[GtalkExtension alloc] init]; + ext.id_p = kIqStreamAck; + ext.data_p = @""; + iq.extension = ext; + return iq; +} + +- (void)sendStreamAck { + GtalkIqStanza *iq = [[self class] createStreamAck]; + [self sendProto:iq]; +} + +- (void)sendClose { + [self sendProto:[[GtalkClose alloc] init]]; +} + +- (void)handleIqStanza:(GtalkIqStanza *)iq { + if (iq.hasExtension) { + if (iq.extension.id_p == kIqStreamAck) { + [self didReceiveStreamAck:iq]; + return; + } + if (iq.extension.id_p == kIqSelectiveAck) { + [self didReceiveSelectiveAck:iq]; + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection009, @"Unknown ack extension id %d.", + iq.extension.id_p); + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection010, @"Ip stanza without extension."); + } + [self didReceiveUnhandledProto:iq]; +} + +- (void)didReceiveLoginResponse:(GtalkLoginResponse *)loginResponse { + if (loginResponse.hasError) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection011, + @"Login error with type: %@, message: %@.", loginResponse.error.type, + loginResponse.error.message); + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection012, @"Logged onto MCS service."); + + self.state = kFIRMessagingConnectionSignedIn; + self.lastLoginServerTimestamp = loginResponse.serverTimestamp; + [self.delegate didLoginWithConnection:self]; + [self sendHeartbeatPing]; + + // Add all the TTL=0 messages on connect + for (GPBMessage *message in self.sendOnConnectMessages) { + [self sendProto:message]; + } + [self.sendOnConnectMessages removeAllObjects]; +} + +- (void)didReceiveHeartbeatPing:(GtalkHeartbeatPing *)heartbeatPing { + [self sendHeartbeatAck]; +} + +- (void)didReceiveHeartbeatAck:(GtalkHeartbeatAck *)heartbeatAck { +} + +- (void)didReceiveDataMessageStanza:(GtalkDataMessageStanza *)dataMessageStanza { + // TODO: Maybe add support raw data later + [self.delegate connectionDidRecieveMessage:dataMessageStanza]; +} + +- (void)didReceiveUnhandledProto:(GPBMessage *)proto { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection013, @"Received unhandled proto"); +} + +- (void)didReceiveStreamAck:(GtalkIqStanza *)iq { + // Server received some stuff from us we don't really need to do anything special +} + +- (void)didReceiveSelectiveAck:(GtalkIqStanza *)iq { + GtalkExtension *extension = iq.extension; + if (extension) { + int extensionId = extension.id_p; + if (extensionId == kIqSelectiveAck) { + NSString *dataString = extension.data_p; + GtalkSelectiveAck *selectiveAck = [[GtalkSelectiveAck alloc] init]; + [selectiveAck mergeFromData:[dataString dataUsingEncoding:NSUTF8StringEncoding] + extensionRegistry:nil]; + + NSArray<NSString *> *acks = [selectiveAck idArray]; + + // we've received ACK's + [self.delegate connectionDidReceiveAckForRmqIds:acks]; + + // resend unacked messages + [self.dataMessageManager resendMessagesWithConnection:self]; + } + } +} + +- (void)didReceiveClose:(GtalkClose *)close { + [self disconnect]; +} + +- (void)willProcessProto:(GPBMessage *)proto { + self.inStreamId++; + + if ([proto isKindOfClass:GtalkDataMessageStanza.class]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection014, + @"RMQ: Receiving %@ with rmq_id: %@ incoming stream Id: %d", + proto.class, FIRMessagingGetRmq2Id(proto), self.inStreamId); + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection015, + @"RMQ: Receiving %@ with incoming stream Id: %d.", proto.class, + self.inStreamId); + } + int streamId = FIRMessagingGetLastStreamId(proto); + if (streamId != kInvalidStreamId) { + // confirm the D2S messages that were sent by us + [self confirmAckedD2sIdsWithStreamId:streamId]; + + // We can now confirm that our ack was received by the server and start our unack'd list fresh + // with the proto we just received. + [self confirmAckedS2dIdsWithStreamId:streamId]; + } + NSString *rmq2Id = FIRMessagingGetRmq2Id(proto); + if (rmq2Id != nil) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection016, + @"RMQ: Add unacked persistent Id: %@.", + [rmq2Id stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); + [self.unackedS2dIds addObject:rmq2Id]; + [self.rmq2Manager saveS2dMessageWithRmqId:rmq2Id]; // RMQ save + } + BOOL explicitAck = ([proto isKindOfClass:[GtalkDataMessageStanza class]] && + [(GtalkDataMessageStanza *)proto immediateAck]); + // If we have not sent anything and the ack threshold has been reached then explicitly send one + // to notify the server that we have received messages. + if (self.inStreamId - self.lastStreamIdAcked >= kAckingInterval || explicitAck) { + [self sendStreamAck]; + } +} + +- (void)willSendProto:(GPBMessage *)proto { + self.outStreamId++; + + NSString *rmq2Id = FIRMessagingGetRmq2Id(proto); + if ([rmq2Id length]) { + FIRMessagingD2SInfo *d2sInfo = [[FIRMessagingD2SInfo alloc] initWithStreamId:self.outStreamId + d2sId:rmq2Id]; + [self.d2sInfos addObject:d2sInfo]; + } + + // each time we send a d2s message, it acks previously received + // s2d messages via the last (s2d) stream id received. + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection017, + @"RMQ: Sending %@ with outgoing stream Id: %d.", proto.class, + self.outStreamId); + // We have received messages since last time we sent something - send ack info to server. + if (self.inStreamId > self.lastStreamIdAcked) { + FIRMessagingSetLastStreamId(proto, self.inStreamId); + self.lastStreamIdAcked = self.inStreamId; + } + + if (self.unackedS2dIds.count > 0) { + // Move all 'unack'd' messages to the ack'd map so they can be removed once the + // ack is confirmed. + NSArray *ackedS2dIds = [NSArray arrayWithArray:self.unackedS2dIds]; + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection018, @"RMQ: Mark persistent Ids as acked: %@.", + [ackedS2dIds.description stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); + [self.unackedS2dIds removeAllObjects]; + self.ackedS2dMap[[@(self.outStreamId) stringValue]] = ackedS2dIds; + } +} + +#pragma mark - Private + +/** + * This processes the s2d message received in reference to the d2s messages + * that we have sent before. + */ +- (void)confirmAckedD2sIdsWithStreamId:(int)lastReceivedStreamId { + NSMutableArray *d2sIdsAcked = [NSMutableArray array]; + for (FIRMessagingD2SInfo *d2sInfo in self.d2sInfos) { + if (lastReceivedStreamId < d2sInfo.streamId) { + break; + } + [d2sIdsAcked addObject:d2sInfo]; + } + + NSMutableArray *rmqIds = [NSMutableArray arrayWithCapacity:[d2sIdsAcked count]]; + // remove ACK'ed messages + for (FIRMessagingD2SInfo *d2sInfo in d2sIdsAcked) { + if ([d2sInfo.d2sID length]) { + [rmqIds addObject:d2sInfo.d2sID]; + } + [self.d2sInfos removeObject:d2sInfo]; + } + [self.delegate connectionDidReceiveAckForRmqIds:rmqIds]; +} + +- (void)confirmAckedS2dIdsWithStreamId:(int)lastReceivedStreamId { + // If the server hasn't received the streamId yet. + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection019, + @"RMQ: Server last received stream Id: %d.", lastReceivedStreamId); + if (lastReceivedStreamId < self.outStreamId) { + // TODO: This could be a good indicator that we need to re-send something (acks)? + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection020, + @"RMQ: There are unsent messages that should be send...\n" + "server received: %d\nlast stream id sent: %d", + lastReceivedStreamId, self.outStreamId); + } + + NSSet *ackedStreamIds = + [self.ackedS2dMap keysOfEntriesPassingTest:^BOOL(id key, id obj, BOOL *stop) { + NSString *streamId = key; + return streamId.intValue <= lastReceivedStreamId; + }]; + NSMutableArray *s2dIdsToDelete = [NSMutableArray array]; + + for (NSString *streamId in ackedStreamIds) { + NSArray *ackedS2dIds = self.ackedS2dMap[streamId]; + if (ackedS2dIds.count > 0) { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeConnection021, + @"RMQ: Mark persistent Ids as confirmed by stream id %@: %@.", streamId, + [ackedS2dIds.description stringByReplacingOccurrencesOfString:@"%" withString:@"%%"]); + [self.ackedS2dMap removeObjectForKey:streamId]; + } + + [s2dIdsToDelete addObjectsFromArray:ackedS2dIds]; + } + + // clean up s2d ids that the server knows we've received. + // we let the server know via a s2d last stream id received in a + // d2s message. the server lets us know it has received our d2s + // message via a d2s last stream id received in a s2d message. + [self.rmq2Manager removeS2dIds:s2dIdsToDelete]; +} + +- (void)resetUnconfirmedAcks { + [self.ackedS2dMap enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [self.unackedS2dIds addObjectsFromArray:obj]; + }]; + [self.ackedS2dMap removeAllObjects]; +} + +- (void)disconnect { + // cancel pending timeout tasks. + [self cancelConnectionTimeoutTask]; + // cancel pending heartbeat. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(sendHeartbeatPing) + object:nil]; + // Unset the delegate. FIRMessagingConnection will not receive further events from the socket from + // now on. + self.socket.delegate = nil; + [self.socket disconnect]; + self.state = kFIRMessagingConnectionNotConnected; +} + +- (void)connectionTimedOut { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection022, + @"Connection to FIRMessaging service timed out."); + [self disconnect]; + [self.delegate connection:self didCloseForReason:kFIRMessagingConnectionCloseReasonTimeout]; +} + +- (void)scheduleConnectionTimeoutTask { + // cancel the previous heartbeat timeout event and schedule a new one. + [self cancelConnectionTimeoutTask]; + [self performSelector:@selector(connectionTimedOut) + withObject:nil + afterDelay:[self connectionTimeoutInterval]]; +} + +- (void)cancelConnectionTimeoutTask { + // cancel pending timeout tasks. + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(connectionTimedOut) + object:nil]; +} + +- (void)logMessage:(NSString *)description messageType:(int)messageType isOut:(BOOL)isOut { + messageType = isOut ? -messageType : messageType; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection023, + @"Send msg: %@ type: %d inStreamId: %d outStreamId: %d", description, + messageType, self.inStreamId, self.outStreamId); +} + +- (NSTimeInterval)connectionTimeoutInterval { + return kConnectionTimeout; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConstants.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConstants.h new file mode 100644 index 00000000..8450f415 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConstants.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +/** + * Global constants to be put here. + * + */ +#import <Foundation/Foundation.h> + +#ifndef _FIRMessaging_CONSTANTS_H +#define _FIRMessaging_CONSTANTS_H + +FOUNDATION_EXPORT NSString *const kFIRMessagingRawDataKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingCollapseKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingFromKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingSendTo; +FOUNDATION_EXPORT NSString *const kFIRMessagingSendTTL; +FOUNDATION_EXPORT NSString *const kFIRMessagingSendDelay; +FOUNDATION_EXPORT NSString *const kFIRMessagingSendMessageID; +FOUNDATION_EXPORT NSString *const KFIRMessagingSendMessageAppData; + +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageInternalReservedKeyword; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessagePersistentIDKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageIDKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageAPNSContentAvailableKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageSyncViaMCSKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageSyncMessageTTLKey; +FOUNDATION_EXPORT NSString *const kFIRMessagingMessageLinkKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey; + +FOUNDATION_EXPORT NSString *const kFIRMessagingSubDirectoryName; + +// Notifications +FOUNDATION_EXPORT NSString *const kFIRMessagingCheckinFetchedNotification; +FOUNDATION_EXPORT NSString *const kFIRMessagingAPNSTokenNotification; +FOUNDATION_EXPORT NSString *const kFIRMessagingRegistrationTokenRefreshNotification; + +FOUNDATION_EXPORT const int kFIRMessagingSendTtlDefault; // 24 hours + +#endif diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConstants.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConstants.m new file mode 100644 index 00000000..34a7cec6 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingConstants.m @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" + +NSString *const kFIRMessagingRawDataKey = @"rawData"; +NSString *const kFIRMessagingCollapseKey = @"collapse_key"; +NSString *const kFIRMessagingFromKey = @"from"; + +NSString *const kFIRMessagingSendTo = @"google." + @"to"; +NSString *const kFIRMessagingSendTTL = @"google." + @"ttl"; +NSString *const kFIRMessagingSendDelay = @"google." + @"delay"; +NSString *const kFIRMessagingSendMessageID = @"google." + @"msg_id"; +NSString *const KFIRMessagingSendMessageAppData = @"google." + @"data"; + +NSString *const kFIRMessagingMessageInternalReservedKeyword = @"gcm."; +NSString *const kFIRMessagingMessagePersistentIDKey = @"persistent_id"; + +NSString *const kFIRMessagingMessageIDKey = @"gcm." + @"message_id"; +NSString *const kFIRMessagingMessageAPNSContentAvailableKey = @"content-available"; +NSString *const kFIRMessagingMessageSyncViaMCSKey = @"gcm." + @"duplex"; +NSString *const kFIRMessagingMessageSyncMessageTTLKey = @"gcm." + @"ttl"; +NSString *const kFIRMessagingMessageLinkKey = @"gcm." + @"app_link"; + +NSString *const kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey = + @"FirebaseAppDelegateProxyEnabled"; + +NSString *const kFIRMessagingSubDirectoryName = @"Google/FirebaseMessaging"; + +// Notifications +NSString *const kFIRMessagingCheckinFetchedNotification = @"com.google.gcm.notif-checkin-fetched"; +NSString *const kFIRMessagingAPNSTokenNotification = @"com.firebase.iid.notif.apns-token"; +NSString *const kFIRMessagingRegistrationTokenRefreshNotification = + @"com.firebase.iid.notif.refresh-token"; + +const int kFIRMessagingSendTtlDefault = 24 * 60 * 60; // 24 hours diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingContextManagerService.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingContextManagerService.h new file mode 100644 index 00000000..83e64442 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingContextManagerService.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerCategory; +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerLocalTimeStart; +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerLocalTimeEnd; +FOUNDATION_EXPORT NSString *const kFIRMessagingContextManagerBodyKey; + +@interface FIRMessagingContextManagerService : NSObject + +/** + * Check if the message is a context manager message or not. + * + * @param message The message to verify. + * + * @return YES if the message is a context manager message else NO. + */ ++ (BOOL)isContextManagerMessage:(NSDictionary *)message; + +/** + * Handle context manager message. + * + * @param message The message to handle. + * + * @return YES if the message was handled successfully else NO. + */ ++ (BOOL)handleContextManagerMessage:(NSDictionary *)message; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m new file mode 100644 index 00000000..aa1e4692 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingContextManagerService.m @@ -0,0 +1,272 @@ +/* + * Copyright 2017 Google + * + * 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. + */ +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ + __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 || __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || \ + __WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 || TARGET_OS_MACCATALYST +#import <UserNotifications/UserNotifications.h> +#endif + +#import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" + +#import "GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h" + +#define kFIRMessagingContextManagerPrefix @"gcm." +#define kFIRMessagingContextManagerPrefixKey @"google.c.cm." +#define kFIRMessagingContextManagerNotificationKeyPrefix @"gcm.notification." + +static NSString *const kLogTag = @"FIRMessagingAnalytics"; + +static NSString *const kLocalTimeFormatString = @"yyyy-MM-dd HH:mm:ss"; + +static NSString *const kContextManagerPrefixKey = kFIRMessagingContextManagerPrefixKey; + +// Local timed messages (format yyyy-mm-dd HH:mm:ss) +NSString *const kFIRMessagingContextManagerLocalTimeStart = + kFIRMessagingContextManagerPrefixKey @"lt_start"; +NSString *const kFIRMessagingContextManagerLocalTimeEnd = + kFIRMessagingContextManagerPrefixKey @"lt_end"; + +// Local Notification Params +NSString *const kFIRMessagingContextManagerBodyKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"body"; +NSString *const kFIRMessagingContextManagerTitleKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"title"; +NSString *const kFIRMessagingContextManagerBadgeKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"badge"; +NSString *const kFIRMessagingContextManagerCategoryKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"click_action"; +NSString *const kFIRMessagingContextManagerSoundKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"sound"; +NSString *const kFIRMessagingContextManagerContentAvailableKey = + kFIRMessagingContextManagerNotificationKeyPrefix @"content-available"; +static NSString *const kFIRMessagingID = kFIRMessagingContextManagerPrefix @"message_id"; +static NSString *const kFIRMessagingAPNSPayloadKey = @"aps"; + +typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) { + FIRMessagingContextManagerMessageTypeNone, + FIRMessagingContextManagerMessageTypeLocalTime, +}; + +@implementation FIRMessagingContextManagerService + ++ (BOOL)isContextManagerMessage:(NSDictionary *)message { + // For now we only support local time in ContextManager. + if (![message[kFIRMessagingContextManagerLocalTimeStart] length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeContextManagerService000, + @"Received message missing local start time, dropped."); + return NO; + } + + return YES; +} + ++ (BOOL)handleContextManagerMessage:(NSDictionary *)message { + NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart]; + if (startTimeString.length) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeContextManagerService001, + @"%@ Received context manager message with local time %@", kLogTag, + startTimeString); + return [self handleContextManagerLocalTimeMessage:message]; + } + + return NO; +} + ++ (BOOL)handleContextManagerLocalTimeMessage:(NSDictionary *)message { + NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart]; + if (!startTimeString) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService002, + @"Invalid local start date format %@. Message dropped", + startTimeString); + return NO; + } + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; + [dateFormatter setDateFormat:kLocalTimeFormatString]; + NSDate *startDate = [dateFormatter dateFromString:startTimeString]; + NSDate *currentDate = [NSDate date]; + + if ([currentDate compare:startDate] == NSOrderedAscending) { + [self scheduleLocalNotificationForMessage:message atDate:startDate]; + } else { + // check end time has not passed + NSString *endTimeString = message[kFIRMessagingContextManagerLocalTimeEnd]; + if (!endTimeString) { + FIRMessagingLoggerInfo( + kFIRMessagingMessageCodeContextManagerService003, + @"No end date specified for message, start date elapsed. Message dropped."); + return YES; + } + + NSDate *endDate = [dateFormatter dateFromString:endTimeString]; + if (!endTimeString) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService004, + @"Invalid local end date format %@. Message dropped", endTimeString); + return NO; + } + + if ([endDate compare:currentDate] == NSOrderedAscending) { + // end date has already passed drop the message + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeContextManagerService005, + @"End date %@ has already passed. Message dropped.", endTimeString); + return YES; + } + + // schedule message right now (buffer 10s) + [self scheduleLocalNotificationForMessage:message + atDate:[currentDate dateByAddingTimeInterval:10]]; + } + return YES; +} + ++ (void)scheduleiOS10LocalNotificationForMessage:(NSDictionary *)message atDate:(NSDate *)date { + NSCalendar *calendar = [NSCalendar currentCalendar]; + if (@available(macOS 10.14, iOS 10.0, watchOS 3.0, tvOS 10.0, *)) { + NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | + NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; + NSDateComponents *dateComponents = [calendar components:(NSCalendarUnit)unit fromDate:date]; + UNCalendarNotificationTrigger *trigger = + [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:NO]; + + UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; + NSDictionary *apsDictionary = message; + + // Badge is universal + if (apsDictionary[kFIRMessagingContextManagerBadgeKey]) { + content.badge = apsDictionary[kFIRMessagingContextManagerBadgeKey]; + } +#if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH + // The following fields are not available on tvOS + if ([apsDictionary[kFIRMessagingContextManagerBodyKey] length]) { + content.body = apsDictionary[kFIRMessagingContextManagerBodyKey]; + } + if ([apsDictionary[kFIRMessagingContextManagerTitleKey] length]) { + content.title = apsDictionary[kFIRMessagingContextManagerTitleKey]; + } + + if (apsDictionary[kFIRMessagingContextManagerSoundKey]) { + content.sound = apsDictionary[kFIRMessagingContextManagerSoundKey]; + } + + if (apsDictionary[kFIRMessagingContextManagerCategoryKey]) { + content.categoryIdentifier = apsDictionary[kFIRMessagingContextManagerCategoryKey]; + } + + NSDictionary *userInfo = [self parseDataFromMessage:message]; + if (userInfo.count) { + content.userInfo = userInfo; + } +#endif + NSString *identifier = apsDictionary[kFIRMessagingID]; + if (!identifier) { + identifier = [NSUUID UUID].UUIDString; + } + + UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier + content:content + trigger:trigger]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center addNotificationRequest:request + withCompletionHandler:^(NSError *_Nullable error) { + if (error) { + FIRMessagingLoggerError( + kFIRMessagingMessageCodeContextManagerServiceFailedLocalSchedule, + @"Failed scheduling local timezone notification: %@.", error); + } + }]; + } +} + ++ (void)scheduleLocalNotificationForMessage:(NSDictionary *)message atDate:(NSDate *)date { + if (@available(macOS 10.14, iOS 10.0, watchOS 3.0, tvOS 10.0, *)) { + [self scheduleiOS10LocalNotificationForMessage:message atDate:date]; + return; + } +#if TARGET_OS_IOS + NSDictionary *apsDictionary = message; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + UILocalNotification *notification = [[UILocalNotification alloc] init]; +#pragma clang diagnostic pop + + // A great way to understand timezones and UILocalNotifications + // http://stackoverflow.com/questions/18424569/understanding-uilocalnotification-timezone + notification.timeZone = [NSTimeZone defaultTimeZone]; + notification.fireDate = date; + + // In the current solution all of the display stuff goes into a special "aps" dictionary + // being sent in the message. + if ([apsDictionary[kFIRMessagingContextManagerBodyKey] length]) { + notification.alertBody = apsDictionary[kFIRMessagingContextManagerBodyKey]; + } + if (@available(iOS 8.2, *)) { + if ([apsDictionary[kFIRMessagingContextManagerTitleKey] length]) { + notification.alertTitle = apsDictionary[kFIRMessagingContextManagerTitleKey]; + } + } + + if (apsDictionary[kFIRMessagingContextManagerSoundKey]) { + notification.soundName = apsDictionary[kFIRMessagingContextManagerSoundKey]; + } + if (apsDictionary[kFIRMessagingContextManagerBadgeKey]) { + notification.applicationIconBadgeNumber = + [apsDictionary[kFIRMessagingContextManagerBadgeKey] integerValue]; + } + if (apsDictionary[kFIRMessagingContextManagerCategoryKey]) { + notification.category = apsDictionary[kFIRMessagingContextManagerCategoryKey]; + } + + NSDictionary *userInfo = [self parseDataFromMessage:message]; + if (userInfo.count) { + notification.userInfo = userInfo; + } + UIApplication *application = [GULAppDelegateSwizzler sharedApplication]; + if (!application) { + return; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [application scheduleLocalNotification:notification]; +#pragma clang diagnostic pop +#endif +} + ++ (NSDictionary *)parseDataFromMessage:(NSDictionary *)message { + NSMutableDictionary *data = [NSMutableDictionary dictionary]; + for (NSObject<NSCopying> *key in message) { + if ([key isKindOfClass:[NSString class]]) { + NSString *keyString = (NSString *)key; + if ([keyString isEqualToString:kFIRMessagingContextManagerContentAvailableKey]) { + continue; + } else if ([keyString hasPrefix:kContextManagerPrefixKey]) { + continue; + } else if ([keyString isEqualToString:kFIRMessagingAPNSPayloadKey]) { + // Local timezone message is scheduled with FCM payload. APNS payload with + // content_available should be ignored and not passed to the scheduled + // messages. + continue; + } + } + data[[key copy]] = message[key]; + } + return [data copy]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h new file mode 100644 index 00000000..e81c7e6b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h @@ -0,0 +1,101 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class GtalkDataMessageStanza; + +@class FIRMessagingClient; +@class FIRMessagingConnection; +@class FIRMessagingReceiver; +@class FIRMessagingRmqManager; +@class FIRMessagingSyncMessageManager; + +@protocol FIRMessagingDataMessageManagerDelegate <NSObject> + +#pragma mark - Downstream Callbacks + +/** + * Invoked when FIRMessaging receives a downstream message via the MCS connection. + * Let's the user know that they have received a new message by invoking the + * App's remoteNotification callback. + * + * @param message The downstream message received by the MCS connection. + */ +- (void)didReceiveMessage:(nonnull NSDictionary *)message + withIdentifier:(nullable NSString *)messageID; + +#pragma mark - Upstream Callbacks + +/** + * Notify the app that FIRMessaging will soon be sending the upstream message requested by the app. + * + * @param messageID The messageId passed in by the app to track this particular message. + * @param error The error in case FIRMessaging cannot send the message upstream. + */ +- (void)willSendDataMessageWithID:(nullable NSString *)messageID error:(nullable NSError *)error; + +/** + * Notify the app that FIRMessaging did successfully send it's message via the MCS + * connection and the message was successfully delivered. + * + * @param messageId The messageId passed in by the app to track this particular + * message. + */ +- (void)didSendDataMessageWithID:(nonnull NSString *)messageId; + +#pragma mark - Server Callbacks + +/** + * Notify the app that FIRMessaging server deleted some messages which exceeded storage limits. + * This indicates the "deleted_messages" message type we received from the server. + */ +- (void)didDeleteMessagesOnServer; + +@end + +/** + * This manages all of the data messages being sent by the client and also the messages that + * were received from the server. + */ +@interface FIRMessagingDataMessageManager : NSObject + +NS_ASSUME_NONNULL_BEGIN + +- (instancetype)initWithDelegate:(id<FIRMessagingDataMessageManagerDelegate>)delegate + client:(FIRMessagingClient *)client + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + syncMessageManager:(FIRMessagingSyncMessageManager *)syncMessageManager; + +- (void)setDeviceAuthID:(NSString *)deviceAuthID secretToken:(NSString *)secretToken; + +- (void)refreshDelayedMessages; + +#pragma mark - Receive + +- (nullable NSDictionary *)processPacket:(GtalkDataMessageStanza *)packet; +- (void)didReceiveParsedMessage:(NSDictionary *)message; + +#pragma mark - Send + +- (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage; +- (void)didSendDataMessageStanza:(GtalkDataMessageStanza *)message; + +- (void)resendMessagesWithConnection:(FIRMessagingConnection *)connection; + +NS_ASSUME_NONNULL_END + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDataMessageManager.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDataMessageManager.m new file mode 100644 index 00000000..2abae6ae --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDataMessageManager.m @@ -0,0 +1,521 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h" + +#import "FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h" + +#import "FirebaseMessaging/Sources/FIRMessagingClient.h" +#import "FirebaseMessaging/Sources/FIRMessagingConnection.h" +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingReceiver.h" +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" + +static const int kMaxAppDataSizeDefault = 4 * 1024; // 4k +static const int kMinDelaySeconds = 1; // 1 second +static const int kMaxDelaySeconds = 60 * 60; // 1 hour + +static NSString *const kFromForFIRMessagingMessages = @"mcs.android.com"; +static NSString *const kGSFMessageCategory = @"com.google.android.gsf.gtalkservice"; +// TODO: Update Gcm to FIRMessaging in the constants below +static NSString *const kFCMMessageCategory = @"com.google.gcm"; +static NSString *const kMessageReservedPrefix = @"google."; + +static NSString *const kFCMMessageSpecialMessage = @"message_type"; + +// special messages sent by the server +static NSString *const kFCMMessageTypeDeletedMessages = @"deleted_messages"; + +static NSString *const kMCSNotificationPrefix = @"gcm.notification."; +static NSString *const kDataMessageNotificationKey = @"notification"; + +typedef NS_ENUM(int8_t, UpstreamForceReconnect) { + // Never force reconnect on upstream messages + kUpstreamForceReconnectOff = 0, + // Force reconnect for TTL=0 upstream messages + kUpstreamForceReconnectTTL0 = 1, + // Force reconnect for all upstream messages + kUpstreamForceReconnectAll = 2, +}; + +@interface FIRMessagingDataMessageManager () + +@property(nonatomic, readwrite, weak) FIRMessagingClient *client; +@property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager; +@property(nonatomic, readwrite, weak) FIRMessagingSyncMessageManager *syncMessageManager; +@property(nonatomic, readwrite, weak) id<FIRMessagingDataMessageManagerDelegate> delegate; +@property(nonatomic, readwrite, strong) FIRMessagingDelayedMessageQueue *delayedMessagesQueue; + +@property(nonatomic, readwrite, assign) int ttl; +@property(nonatomic, readwrite, copy) NSString *deviceAuthID; +@property(nonatomic, readwrite, copy) NSString *secretToken; +@property(nonatomic, readwrite, assign) int maxAppDataSize; +@property(nonatomic, readwrite, assign) UpstreamForceReconnect upstreamForceReconnect; + +@end + +@implementation FIRMessagingDataMessageManager + +- (instancetype)initWithDelegate:(id<FIRMessagingDataMessageManagerDelegate>)delegate + client:(FIRMessagingClient *)client + rmq2Manager:(FIRMessagingRmqManager *)rmq2Manager + syncMessageManager:(FIRMessagingSyncMessageManager *)syncMessageManager { + self = [super init]; + if (self) { + _delegate = delegate; + _client = client; + _rmq2Manager = rmq2Manager; + _syncMessageManager = syncMessageManager; + _ttl = kFIRMessagingSendTtlDefault; + _maxAppDataSize = kMaxAppDataSizeDefault; + // on by default + _upstreamForceReconnect = kUpstreamForceReconnectAll; + } + return self; +} + +- (void)setDeviceAuthID:(NSString *)deviceAuthID secretToken:(NSString *)secretToken { + if (deviceAuthID.length == 0 || secretToken.length == 0) { + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeDataMessageManager013, + @"Invalid credentials: deviceAuthID: %@, secrectToken: %@", deviceAuthID, + secretToken); + } + self.deviceAuthID = deviceAuthID; + self.secretToken = secretToken; +} + +- (void)refreshDelayedMessages { + FIRMessaging_WEAKIFY(self); + self.delayedMessagesQueue = + [[FIRMessagingDelayedMessageQueue alloc] initWithRmqScanner:self.rmq2Manager + sendDelayedMessagesHandler:^(NSArray *messages) { + FIRMessaging_STRONGIFY(self); + [self sendDelayedMessages:messages]; + }]; +} + +- (nullable NSDictionary *)processPacket:(GtalkDataMessageStanza *)dataMessage { + NSString *category = dataMessage.category; + NSString *from = dataMessage.from; + if ([kFCMMessageCategory isEqualToString:category] || + [kGSFMessageCategory isEqualToString:category]) { + [self handleMCSDataMessage:dataMessage]; + return nil; + } else if ([kFromForFIRMessagingMessages isEqualToString:from]) { + [self handleMCSDataMessage:dataMessage]; + return nil; + } + + return [self parseDataMessage:dataMessage]; +} + +- (void)handleMCSDataMessage:(GtalkDataMessageStanza *)dataMessage { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager000, + @"Received message for FIRMessaging from downstream %@", dataMessage); +} + +- (NSDictionary *)parseDataMessage:(GtalkDataMessageStanza *)dataMessage { + NSMutableDictionary *message = [NSMutableDictionary dictionary]; + NSString *from = [dataMessage from]; + if (from.length) { + message[kFIRMessagingFromKey] = from; + } + + // raw data + NSData *rawData = [dataMessage rawData]; + if (rawData.length) { + message[kFIRMessagingRawDataKey] = rawData; + } + + NSString *token = [dataMessage token]; + if (token.length) { + message[kFIRMessagingCollapseKey] = token; + } + + // Add the persistent_id. This would be removed later before sending the message to the device. + NSString *persistentID = [dataMessage persistentId]; + if (persistentID.length) { + message[kFIRMessagingMessageIDKey] = persistentID; + } + + // third-party data + for (GtalkAppData *item in dataMessage.appDataArray) { + // do not process the "from" key -- is not useful + if ([kFIRMessagingFromKey isEqualToString:item.key]) { + continue; + } + + // Filter the "gcm.notification." keys in the message + if ([item.key hasPrefix:kMCSNotificationPrefix]) { + NSString *key = [item.key substringFromIndex:[kMCSNotificationPrefix length]]; + if ([key length]) { + if (!message[kDataMessageNotificationKey]) { + message[kDataMessageNotificationKey] = [NSMutableDictionary dictionary]; + } + message[kDataMessageNotificationKey][key] = item.value; + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager001, + @"Invalid key in MCS message: %@", key); + } + continue; + } + + // Filter the "gcm.duplex" key + if ([item.key isEqualToString:kFIRMessagingMessageSyncViaMCSKey]) { + BOOL value = [item.value boolValue]; + message[kFIRMessagingMessageSyncViaMCSKey] = @(value); + continue; + } + + // do not allow keys with "reserved" keyword + if ([[item.key lowercaseString] hasPrefix:kMessageReservedPrefix]) { + continue; + } + + [message setObject:item.value forKey:item.key]; + } + // TODO: Add support for encrypting raw data later + return [NSDictionary dictionaryWithDictionary:message]; +} + +- (void)didReceiveParsedMessage:(NSDictionary *)message { + if ([message[kFCMMessageSpecialMessage] length]) { + NSString *messageType = message[kFCMMessageSpecialMessage]; + if ([kFCMMessageTypeDeletedMessages isEqualToString:messageType]) { + // TODO: Maybe trim down message to remove some unnecessary fields. + // tell the FCM receiver of deleted messages + [self.delegate didDeleteMessagesOnServer]; + return; + } + FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager002, + @"Invalid message type received: %@", messageType); + } else if (message[kFIRMessagingMessageSyncViaMCSKey]) { + // Update SYNC_RMQ with the message + BOOL isDuplicate = [self.syncMessageManager didReceiveMCSSyncMessage:message]; + if (isDuplicate) { + return; + } + } + NSString *messageId = message[kFIRMessagingMessageIDKey]; + NSDictionary *filteredMessage = [self filterInternalFIRMessagingKeysFromMessage:message]; + [self.delegate didReceiveMessage:filteredMessage withIdentifier:messageId]; +} + +- (NSDictionary *)filterInternalFIRMessagingKeysFromMessage:(NSDictionary *)message { + NSMutableDictionary *newMessage = [NSMutableDictionary dictionaryWithDictionary:message]; + for (NSString *key in message) { + if ([key hasPrefix:kFIRMessagingMessageInternalReservedKeyword]) { + [newMessage removeObjectForKey:key]; + } + } + return [newMessage copy]; +} + +- (void)sendDataMessageStanza:(NSMutableDictionary *)dataMessage { + NSNumber *ttlNumber = dataMessage[kFIRMessagingSendTTL]; + NSString *to = dataMessage[kFIRMessagingSendTo]; + NSString *msgId = dataMessage[kFIRMessagingSendMessageID]; + NSString *appPackage = [self categoryForUpstreamMessages]; + GtalkDataMessageStanza *stanza = [[GtalkDataMessageStanza alloc] init]; + + // TODO: enforce TTL (right now only ttl=0 is special, means no storage) + int ttl = [ttlNumber intValue]; + if (ttl < 0 || ttl > self.ttl) { + ttl = self.ttl; + } + [stanza setTtl:ttl]; + [stanza setSent:FIRMessagingCurrentTimestampInSeconds()]; + + int delay = [self delayForMessage:dataMessage]; + if (delay > 0) { + [stanza setMaxDelay:delay]; + } + + if (msgId) { + [stanza setId_p:msgId]; + } + + // collapse key as given by the sender + NSString *token = dataMessage[KFIRMessagingSendMessageAppData][kFIRMessagingCollapseKey]; + if ([token length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager003, + @"FIRMessaging using %@ as collapse key", token); + [stanza setToken:token]; + } + + if (!self.secretToken) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager004, + @"Trying to send data message without a secret token. " + @"Authentication failed."); + [self willSendDataMessageFail:stanza + withMessageId:msgId + error:kFIRMessagingErrorCodeMissingDeviceID]; + return; + } + + if (![to length]) { + [self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorCodeMissingTo]; + return; + } + [stanza setTo:to]; + [stanza setCategory:appPackage]; + // required field in the proto this is set by the server + // set it to a sentinel so the runtime doesn't throw an exception + [stanza setFrom:@""]; + + // MCS itself would set the registration ID + // [stanza setRegId:nil]; + + int size = [self addData:dataMessage[KFIRMessagingSendMessageAppData] toStanza:stanza]; + if (size > kMaxAppDataSizeDefault) { + [self willSendDataMessageFail:stanza + withMessageId:msgId + error:kFIRMessagingErrorCodeSizeExceeded]; + return; + } + + BOOL useRmq = (ttl != 0) && (msgId != nil); + if (useRmq) { + [self.rmq2Manager saveRmqMessage:stanza + withCompletionHandler:^(BOOL success) { + if (!success) { + [self willSendDataMessageFail:stanza + withMessageId:msgId + error:kFIRMessagingErrorCodeSave]; + return; + } + [self willSendDataMessageSuccess:stanza withMessageId:msgId]; + }]; + } + + // if delay > 0 we don't really care about sending the message right now + // so we piggy-back on any other urgent(delay = 0) message that we are sending + if (delay > 0 && [self delayMessage:stanza]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager006, @"Delaying Message %@", + dataMessage); + return; + } + // send delayed messages + [self sendDelayedMessages:[self.delayedMessagesQueue removeDelayedMessages]]; + + BOOL sending = [self tryToSendDataMessageStanza:stanza]; + if (!sending) { + if (useRmq) { + NSString *event __unused = [NSString stringWithFormat:@"Queued message: %@", [stanza id_p]]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager007, @"%@", event); + } else { + [self willSendDataMessageFail:stanza withMessageId:msgId error:kFIRMessagingErrorCodeNetwork]; + return; + } + } +} + +- (void)sendDelayedMessages:(NSArray *)delayedMessages { + for (GtalkDataMessageStanza *message in delayedMessages) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager008, + @"%@ Sending delayed message %@", @"DMM", message); + [message setActualDelay:(int)(FIRMessagingCurrentTimestampInSeconds() - message.sent)]; + [self tryToSendDataMessageStanza:message]; + } +} + +- (void)didSendDataMessageStanza:(GtalkDataMessageStanza *)message { + NSString *msgId = [message id_p] ?: @""; + [self.delegate didSendDataMessageWithID:msgId]; +} + +- (void)addParamWithKey:(NSString *)key + value:(NSString *)val + toStanza:(GtalkDataMessageStanza *)stanza { + if (!key || !val) { + return; + } + GtalkAppData *appData = [[GtalkAppData alloc] init]; + [appData setKey:key]; + [appData setValue:val]; + [[stanza appDataArray] addObject:appData]; +} + +/** + @return The size of the data being added to stanza. + */ +- (int)addData:(NSDictionary *)data toStanza:(GtalkDataMessageStanza *)stanza { + int size = 0; + for (NSString *key in data) { + NSObject *val = data[key]; + if ([val isKindOfClass:[NSString class]]) { + NSString *strVal = (NSString *)val; + [self addParamWithKey:key value:strVal toStanza:stanza]; + size += [key length] + [strVal length]; + } else if ([val isKindOfClass:[NSNumber class]]) { + NSString *strVal = [(NSNumber *)val stringValue]; + [self addParamWithKey:key value:strVal toStanza:stanza]; + size += [key length] + [strVal length]; + } else if ([kFIRMessagingRawDataKey isEqualToString:key] && + [val isKindOfClass:[NSData class]]) { + NSData *rawData = (NSData *)val; + [stanza setRawData:[rawData copy]]; + size += [rawData length]; + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager009, @"Ignoring key: %@", + key); + } + } + return size; +} + +/** + * Notify the messenger that send data message completed with success. This is called for + * TTL=0, after the message has been sent, or when message is saved, to unlock the send() + * method. + */ +- (void)willSendDataMessageSuccess:(GtalkDataMessageStanza *)stanza + withMessageId:(NSString *)messageId { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager010, + @"send message success: %@", messageId); + [self.delegate willSendDataMessageWithID:messageId error:nil]; +} + +/** + * We send 'send failures' from server as normal FIRMessaging messages, with a 'message_type' + * extra - same as 'message deleted'. + * + * For TTL=0 or errors that can be detected during send ( too many messages, invalid, etc) + * we throw IOExceptions + */ +- (void)willSendDataMessageFail:(GtalkDataMessageStanza *)stanza + withMessageId:(NSString *)messageId + error:(FIRMessagingErrorCode)errorCode { + NSString *failureReason = [NSString + stringWithFormat:@"Send message fail: %@ error: %lu", messageId, (unsigned long)errorCode]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager011, @"%@", failureReason); + + NSError *error = [NSError messagingErrorWithCode:errorCode failureReason:failureReason]; + if ([self.delegate respondsToSelector:@selector(willSendDataMessageWithID:error:)]) { + [self.delegate willSendDataMessageWithID:messageId error:error]; + } +} + +- (void)resendMessagesWithConnection:(FIRMessagingConnection *)connection { + NSMutableString *rmqIdsResent = [NSMutableString string]; + NSMutableArray *toRemoveRmqIds = [NSMutableArray array]; + FIRMessaging_WEAKIFY(self); + FIRMessaging_WEAKIFY(connection); + + [self.rmq2Manager scanWithRmqMessageHandler:^(NSDictionary *messages) { + FIRMessaging_STRONGIFY(self); + FIRMessaging_STRONGIFY(connection); + for (NSString *rmqID in messages) { + GPBMessage *proto = messages[rmqID]; + if ([proto isKindOfClass:GtalkDataMessageStanza.class]) { + GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)proto; + if (![self handleExpirationForDataMessage:stanza]) { + // time expired let's delete from RMQ + [toRemoveRmqIds addObject:stanza.persistentId]; + continue; + } + [rmqIdsResent appendString:[NSString stringWithFormat:@"%@,", stanza.id_p]]; + } + [connection sendProto:proto]; + } + if ([rmqIdsResent length]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDataMessageManager012, @"Resent: %@", + rmqIdsResent); + } + if ([toRemoveRmqIds count]) { + [self.rmq2Manager removeRmqMessagesWithRmqIds:[toRemoveRmqIds copy]]; + } + }]; +} + +/** + * Check the TTL and generate an error if needed. + * + * @return false if the message needs to be deleted + */ +- (BOOL)handleExpirationForDataMessage:(GtalkDataMessageStanza *)message { + if (message.ttl == 0) { + return NO; + } + + int64_t now = FIRMessagingCurrentTimestampInSeconds(); + if (now > message.sent + message.ttl) { + [self willSendDataMessageFail:message + withMessageId:message.id_p + error:kFIRMessagingErrorCodeServiceNotAvailable]; + return NO; + } + return YES; +} + +#pragma mark - Private + +- (int)delayForMessage:(NSMutableDictionary *)message { + int delay = 0; // default + if (message[kFIRMessagingSendDelay]) { + delay = [message[kFIRMessagingSendDelay] intValue]; + [message removeObjectForKey:kFIRMessagingSendDelay]; + if (delay < kMinDelaySeconds) { + delay = 0; + } else if (delay > kMaxDelaySeconds) { + delay = kMaxDelaySeconds; + } + } + return delay; +} + +// return True if successfully delayed else False +- (BOOL)delayMessage:(GtalkDataMessageStanza *)message { + return [self.delayedMessagesQueue queueMessage:message]; +} + +- (BOOL)tryToSendDataMessageStanza:(GtalkDataMessageStanza *)stanza { + if (self.client.isConnectionActive) { + [self.client sendMessage:stanza]; + return YES; + } + + // if we only reconnect for TTL = 0 messages check if we ttl = 0 or + // if we reconnect for all messages try to reconnect + if ((self.upstreamForceReconnect == kUpstreamForceReconnectTTL0 && stanza.ttl == 0) || + self.upstreamForceReconnect == kUpstreamForceReconnectAll) { + BOOL isNetworkAvailable = [[FIRMessaging messaging] isNetworkAvailable]; + if (isNetworkAvailable) { + if (stanza.ttl == 0) { + // Add TTL = 0 messages to be sent on next connect. TTL != 0 messages are + // persisted, and will be sent from the RMQ. + [self.client sendOnConnectOrDrop:stanza]; + } + + [self.client retryConnectionImmediately:YES]; + return YES; + } + } + return NO; +} + +- (NSString *)categoryForUpstreamMessages { + return FIRMessagingAppIdentifier(); +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDefines.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDefines.h new file mode 100644 index 00000000..e7643ae4 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDefines.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRMessaging_xcodeproj_FIRMessagingDefines_h +#define FIRMessaging_xcodeproj_FIRMessagingDefines_h + +// WEAKIFY & STRONGIFY +// Helper macro. +#define _FIRMessaging_WEAKNAME(VAR) VAR##_weak_ + +#define FIRMessaging_WEAKIFY(VAR) __weak __typeof__(VAR) _FIRMessaging_WEAKNAME(VAR) = (VAR); + +#define FIRMessaging_STRONGIFY(VAR) \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") \ + __strong __typeof__(VAR) VAR = _FIRMessaging_WEAKNAME(VAR); \ + _Pragma("clang diagnostic pop") + +#ifndef _FIRMessaging_UL +#define _FIRMessaging_UL(v) (unsigned long)(v) +#endif + +#endif + +// Invalidates the initializer from which it's called. +#ifndef FIRMessagingInvalidateInitializer +#define FIRMessagingInvalidateInitializer() \ + do { \ + [self class]; /* Avoid warning of dead store to |self|. */ \ + NSAssert(NO, @"Invalid initializer."); \ + return nil; \ + } while (0) +#endif diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.h new file mode 100644 index 00000000..51da87b0 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.h @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class GtalkDataMessageStanza; +@class FIRMessagingRmqManager; + +@protocol FIRMessagingRmqScanner; + +typedef void (^FIRMessagingSendDelayedMessagesHandler)(NSArray *messages); + +@interface FIRMessagingDelayedMessageQueue : NSObject + +- (instancetype)initWithRmqScanner:(id<FIRMessagingRmqScanner>)rmqScanner + sendDelayedMessagesHandler: + (FIRMessagingSendDelayedMessagesHandler)sendDelayedMessagesHandler; + +- (BOOL)queueMessage:(GtalkDataMessageStanza *)message; + +- (NSArray *)removeDelayedMessages; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.m new file mode 100644 index 00000000..24ca8800 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.m @@ -0,0 +1,149 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingDelayedMessageQueue.h" + +#import "FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" + +static const int kMaxQueuedMessageCount = 10; + +@interface FIRMessagingDelayedMessageQueue () + +@property(nonatomic, readonly, weak) id<FIRMessagingRmqScanner> rmqScanner; +@property(nonatomic, readonly, copy) + FIRMessagingSendDelayedMessagesHandler sendDelayedMessagesHandler; + +@property(nonatomic, readwrite, assign) int persistedMessageCount; +// the scheduled timeout or -1 if not set +@property(nonatomic, readwrite, assign) int64_t scheduledTimeoutMilliseconds; +// The time of the last scan of the message DB, +// used to avoid retrieving messages more than once. +@property(nonatomic, readwrite, assign) int64_t lastDBScanTimestampSeconds; + +@property(nonatomic, readwrite, strong) NSMutableArray *messages; +@property(nonatomic, readwrite, strong) NSTimer *sendTimer; + +@end + +@implementation FIRMessagingDelayedMessageQueue + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithRmqScanner:(id<FIRMessagingRmqScanner>)rmqScanner + sendDelayedMessagesHandler: + (FIRMessagingSendDelayedMessagesHandler)sendDelayedMessagesHandler { + self = [super init]; + if (self) { + _rmqScanner = rmqScanner; + _sendDelayedMessagesHandler = sendDelayedMessagesHandler; + _messages = [NSMutableArray arrayWithCapacity:10]; + _scheduledTimeoutMilliseconds = -1; + } + return self; +} + +- (BOOL)queueMessage:(GtalkDataMessageStanza *)message { + if (self.messages.count >= kMaxQueuedMessageCount) { + return NO; + } + if (message.ttl == 0) { + // ttl=0 messages aren't persisted, add it to memory + [self.messages addObject:message]; + } else { + self.persistedMessageCount++; + } + int64_t timeoutMillis = [self calculateTimeoutInMillisWithDelayInSeconds:message.maxDelay]; + if (![self isTimeoutScheduled] || timeoutMillis < self.scheduledTimeoutMilliseconds) { + [self scheduleTimeoutInMillis:timeoutMillis]; + } + return YES; +} + +- (NSArray *)removeDelayedMessages { + [self cancelTimeout]; + if ([self messageCount] == 0) { + return @[]; + } + + NSMutableArray *delayedMessages = [NSMutableArray array]; + // add the ttl=0 messages + if (self.messages.count) { + [delayedMessages addObjectsFromArray:delayedMessages]; + [self.messages removeAllObjects]; + } + + // add persistent messages + if (self.persistedMessageCount > 0) { + FIRMessaging_WEAKIFY(self); + [self.rmqScanner scanWithRmqMessageHandler:^(NSDictionary *messages) { + FIRMessaging_STRONGIFY(self); + for (NSString *rmqID in messages) { + GPBMessage *proto = messages[rmqID]; + GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)proto; + if ([stanza hasMaxDelay] && [stanza sent] >= self.lastDBScanTimestampSeconds) { + [delayedMessages addObject:stanza]; + } + } + }]; + self.lastDBScanTimestampSeconds = FIRMessagingCurrentTimestampInSeconds(); + self.persistedMessageCount = 0; + } + return delayedMessages; +} + +- (void)sendMessages { + if (self.sendDelayedMessagesHandler) { + self.sendDelayedMessagesHandler([self removeDelayedMessages]); + } +} + +#pragma mark - Private + +- (NSInteger)messageCount { + return self.messages.count + self.persistedMessageCount; +} + +- (BOOL)isTimeoutScheduled { + return self.scheduledTimeoutMilliseconds > 0; +} + +- (int64_t)calculateTimeoutInMillisWithDelayInSeconds:(int)delay { + return FIRMessagingCurrentTimestampInMilliseconds() + delay * 1000.0; +} + +- (void)scheduleTimeoutInMillis:(int64_t)time { + [self cancelTimeout]; + self.scheduledTimeoutMilliseconds = time; + double delay = (time - FIRMessagingCurrentTimestampInMilliseconds()) / 1000.0; + [self performSelector:@selector(sendMessages) withObject:self afterDelay:delay]; +} + +- (void)cancelTimeout { + if ([self isTimeoutScheduled]) { + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(sendMessages) + object:nil]; + self.scheduledTimeoutMilliseconds = -1; + } +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingExtensionHelper.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingExtensionHelper.m new file mode 100644 index 00000000..013f3596 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingExtensionHelper.m @@ -0,0 +1,119 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessagingExtensionHelper.h> + +#import "FirebaseMessaging/Sources/FIRMMessageCode.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" + +static NSString *const kPayloadOptionsName = @"fcm_options"; +static NSString *const kPayloadOptionsImageURLName = @"image"; + +@interface FIRMessagingExtensionHelper () +@property(nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver); +@property(nonatomic, strong) UNMutableNotificationContent *bestAttemptContent; + +@end + +@implementation FIRMessagingExtensionHelper + +- (void)populateNotificationContent:(UNMutableNotificationContent *)content + withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler { + self.contentHandler = [contentHandler copy]; + self.bestAttemptContent = content; + + // The `userInfo` property isn't available on newer versions of tvOS. +#if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH + NSString *currentImageURL = content.userInfo[kPayloadOptionsName][kPayloadOptionsImageURLName]; + if (!currentImageURL) { + [self deliverNotification]; + return; + } + NSURL *attachmentURL = [NSURL URLWithString:currentImageURL]; + if (attachmentURL) { + [self loadAttachmentForURL:attachmentURL + completionHandler:^(UNNotificationAttachment *attachment) { + if (attachment != nil) { + self.bestAttemptContent.attachments = @[ attachment ]; + } + [self deliverNotification]; + }]; + } else { + FIRMessagingLoggerError(kFIRMessagingServiceExtensionImageInvalidURL, + @"The Image URL provided is invalid %@.", currentImageURL); + [self deliverNotification]; + } +#else + [self deliverNotification]; +#endif +} + +#if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH +- (void)loadAttachmentForURL:(NSURL *)attachmentURL + completionHandler:(void (^)(UNNotificationAttachment *))completionHandler { + __block UNNotificationAttachment *attachment = nil; + + NSURLSession *session = [NSURLSession + sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [[session + downloadTaskWithURL:attachmentURL + completionHandler:^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) { + if (error != nil) { + FIRMessagingLoggerError(kFIRMessagingServiceExtensionImageNotDownloaded, + @"Failed to download image given URL %@, error: %@\n", + attachmentURL, error); + completionHandler(attachment); + return; + } + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *fileExtension = + [NSString stringWithFormat:@".%@", [response.suggestedFilename pathExtension]]; + NSURL *localURL = [NSURL + fileURLWithPath:[temporaryFileLocation.path stringByAppendingString:fileExtension]]; + [fileManager moveItemAtURL:temporaryFileLocation toURL:localURL error:&error]; + if (error) { + FIRMessagingLoggerError( + kFIRMessagingServiceExtensionLocalFileNotCreated, + @"Failed to move the image file to local location: %@, error: %@\n", localURL, + error); + completionHandler(attachment); + return; + } + + attachment = [UNNotificationAttachment attachmentWithIdentifier:@"" + URL:localURL + options:nil + error:&error]; + if (error) { + FIRMessagingLoggerError(kFIRMessagingServiceExtensionImageNotAttached, + @"Failed to create attachment with URL %@, error: %@\n", + localURL, error); + completionHandler(attachment); + return; + } + completionHandler(attachment); + }] resume]; +} +#endif + +- (void)deliverNotification { + if (self.contentHandler) { + self.contentHandler(self.bestAttemptContent); + } +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingLogger.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingLogger.h new file mode 100644 index 00000000..6b6b4ccc --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingLogger.h @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRMMessageCode.h" + +// The convenience macros are only defined if they haven't already been defined. +#ifndef FIRMessagingLoggerInfo + +// Convenience macros that log to the shared FIRMessagingLogger instance. These macros +// are how users should typically log to FIRMessagingLogger. +#define FIRMessagingLoggerDebug(code, ...) \ + [FIRMessagingSharedLogger() logFuncDebug:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerInfo(code, ...) \ + [FIRMessagingSharedLogger() logFuncInfo:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerNotice(code, ...) \ + [FIRMessagingSharedLogger() logFuncNotice:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerWarn(code, ...) \ + [FIRMessagingSharedLogger() logFuncWarning:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRMessagingLoggerError(code, ...) \ + [FIRMessagingSharedLogger() logFuncError:__func__ messageCode:code msg:__VA_ARGS__] + +#endif // !defined(FIRMessagingLoggerInfo) + +@interface FIRMessagingLogger : NSObject + +- (void)logFuncDebug:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncInfo:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncNotice:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncWarning:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncError:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +@end + +/** + * Instantiates and/or returns a shared FIRMessagingLogger used exclusively + * for FIRMessaging log messages. + * + * @return the shared FIRMessagingLogger instance + */ +FIRMessagingLogger *FIRMessagingSharedLogger(void); diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingLogger.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingLogger.m new file mode 100644 index 00000000..57fb1068 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingLogger.m @@ -0,0 +1,95 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" + +#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h" + +FIRLoggerService kFIRLoggerMessaging = @"[Firebase/Messaging]"; + +@implementation FIRMessagingLogger + ++ (instancetype)standardLogger { + return [[FIRMessagingLogger alloc] init]; +} + +#pragma mark - Log Helpers + ++ (NSString *)formatMessageCode:(FIRMessagingMessageCode)messageCode { + return [NSString stringWithFormat:@"I-FCM%06ld", (long)messageCode]; +} + +- (void)logFuncDebug:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncInfo:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelInfo, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncNotice:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelNotice, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncWarning:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncError:(const char *)func + messageCode:(FIRMessagingMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelError, kFIRLoggerMessaging, + [FIRMessagingLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +@end + +FIRMessagingLogger *FIRMessagingSharedLogger(void) { + static dispatch_once_t onceToken; + static FIRMessagingLogger *logger; + dispatch_once(&onceToken, ^{ + logger = [FIRMessagingLogger standardLogger]; + }); + + return logger; +} diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPacketQueue.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPacketQueue.h new file mode 100644 index 00000000..aff03e30 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPacketQueue.h @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@interface FIRMessagingPacket : NSObject + ++ (FIRMessagingPacket *)packetWithTag:(int8_t)tag rmqId:(NSString *)rmqId data:(NSData *)data; + +@property(nonatomic, readonly, strong) NSData *data; +@property(nonatomic, readonly, assign) int8_t tag; +// not sent over the wire required for bookkeeping +@property(nonatomic, readonly, assign) NSString *rmqId; + +@end + +/** + * A queue of the packets(protos) that need to be send over the wire. + */ +@interface FIRMessagingPacketQueue : NSObject + +@property(nonatomic, readonly, assign) NSUInteger count; +@property(nonatomic, readonly, assign) BOOL isEmpty; + +- (void)push:(FIRMessagingPacket *)packet; +- (void)pushHead:(FIRMessagingPacket *)packet; +- (FIRMessagingPacket *)pop; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPacketQueue.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPacketQueue.m new file mode 100644 index 00000000..b0efe7fe --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPacketQueue.m @@ -0,0 +1,103 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingPacketQueue.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" + +@interface FIRMessagingPacket () + +@property(nonatomic, readwrite, strong) NSData *data; +@property(nonatomic, readwrite, assign) int8_t tag; +@property(nonatomic, readwrite, assign) NSString *rmqId; + +@end + +@implementation FIRMessagingPacket + ++ (FIRMessagingPacket *)packetWithTag:(int8_t)tag rmqId:(NSString *)rmqId data:(NSData *)data { + return [[self alloc] initWithTag:tag rmqId:rmqId data:data]; +} + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithTag:(int8_t)tag rmqId:(NSString *)rmqId data:(NSData *)data { + self = [super init]; + if (self != nil) { + _data = data; + _tag = tag; + _rmqId = rmqId; + } + return self; +} + +- (NSString *)description { + if ([self.rmqId length]) { + return [NSString stringWithFormat:@"<Packet: Tag - %d, Length - %lu>, RmqId - %@", self.tag, + _FIRMessaging_UL(self.data.length), self.rmqId]; + } else { + return [NSString stringWithFormat:@"<Packet: Tag - %d, Length - %lu>", self.tag, + _FIRMessaging_UL(self.data.length)]; + } +} + +@end + +@interface FIRMessagingPacketQueue () + +@property(nonatomic, readwrite, strong) NSMutableArray *packetsContainer; + +@end + +@implementation FIRMessagingPacketQueue +; + +- (id)init { + self = [super init]; + if (self) { + _packetsContainer = [[NSMutableArray alloc] init]; + } + return self; +} + +- (BOOL)isEmpty { + return self.packetsContainer.count == 0; +} + +- (NSUInteger)count { + return self.packetsContainer.count; +} + +- (void)push:(FIRMessagingPacket *)packet { + [self.packetsContainer addObject:packet]; +} + +- (void)pushHead:(FIRMessagingPacket *)packet { + [self.packetsContainer insertObject:packet atIndex:0]; +} + +- (FIRMessagingPacket *)pop { + if (!self.isEmpty) { + FIRMessagingPacket *packet = self.packetsContainer[0]; + [self.packetsContainer removeObjectAtIndex:0]; + return packet; + } + return nil; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.h new file mode 100644 index 00000000..2f3d8fc2 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#import <FirebaseMessaging/FIRMessaging.h> + +#import "FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents a single batch of topics, with the same action. + * + * Topic operations which have the same action (subscribe or unsubscribe) can be executed + * simultaneously, as the order of operations do not matter with the same action. The set of + * topics is unique, as it doesn't make sense to apply the same action to the same topic + * repeatedly; the result would be the same as the first time. + */ +@interface FIRMessagingTopicBatch : NSObject <NSSecureCoding> + +@property(nonatomic, readonly, assign) FIRMessagingTopicAction action; +@property(nonatomic, readonly, copy) NSMutableSet<NSString *> *topics; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithAction:(FIRMessagingTopicAction)action NS_DESIGNATED_INITIALIZER; + +@end + +@class FIRMessagingPendingTopicsList; +/** + * This delegate must be supplied to the instance of FIRMessagingPendingTopicsList, via the + * @cdelegate property. It lets the + * pending topics list know whether or not it can begin making requests via + * @c-pendingTopicsListCanRequestTopicUpdates:, and handles the request to actually + * perform the topic operation. The delegate also handles when the pending topics list is updated, + * so that it can be archived or persisted. + * + * @see FIRMessagingPendingTopicsList + */ +@protocol FIRMessagingPendingTopicsListDelegate <NSObject> + +- (void)pendingTopicsList:(FIRMessagingPendingTopicsList *)list + requestedUpdateForTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + completion:(FIRMessagingTopicOperationCompletion)completion; +- (void)pendingTopicsListDidUpdate:(FIRMessagingPendingTopicsList *)list; +- (BOOL)pendingTopicsListCanRequestTopicUpdates:(FIRMessagingPendingTopicsList *)list; + +@end + +/** + * FIRMessagingPendingTopicsList manages a list of topic subscription updates, batched by the same + * action (subscribe or unsubscribe). The list roughly maintains the order of the topic operations, + * batched together whenever the topic action (subscribe or unsubscribe) changes. + * + * Topics operations are batched by action because it is safe to perform the same topic action + * (subscribe or unsubscribe) on many topics simultaneously. After each batch is successfully + * completed, the next batch operations can begin. + * + * When asked to resume its operations, FIRMessagingPendingTopicsList will begin performing updates + * of its current batch of topics. For example, it may begin subscription operations for topics + * [A, B, C] simultaneously. + * + * When the current batch is completed, the next batch of operations will be started. For example + * the list may begin unsubscribe operations for [D, A, E]. Note that because A is in both batches, + * A will be correctly subscribed in the first batch, then unsubscribed as part of the second batch + * of operations. Without batching, it would be ambiguous whether A's subscription operation or the + * unsubscription operation would be completed first. + * + * An app can subscribe and unsubscribe from many topics, and this class helps persist the pending + * topics and perform the operation safely and correctly. + * + * When a topic fails to subscribe or unsubscribe due to a network error, it is considered a + * recoverable error, and so it remains in the current batch until it is succesfully completed. + * Topic updates are completed when they either (a) succeed, (b) are cancelled, or (c) result in an + * unrecoverable error. Any error outside of `NSURLErrorDomain` is considered an unrecoverable + * error. + * + * In addition to maintaining the list of pending topic updates, FIRMessagingPendingTopicsList also + * can track completion handlers for topic operations. + * + * @discussion Completion handlers for topic updates are not maintained if it was restored from a + * keyed archive. They are only called if the topic operation finished within the same app session. + * + * You must supply an object conforming to FIRMessagingPendingTopicsListDelegate in order for the + * topic operations to execute. + * + * @see FIRMessagingPendingTopicsListDelegate + */ +@interface FIRMessagingPendingTopicsList : NSObject <NSSecureCoding> + +@property(nonatomic, weak) NSObject<FIRMessagingPendingTopicsListDelegate> *delegate; + +@property(nonatomic, readonly, strong, nullable) NSDate *archiveDate; +@property(nonatomic, readonly) NSUInteger numberOfBatches; + +- (instancetype)init NS_DESIGNATED_INITIALIZER; +- (void)addOperationForTopic:(NSString *)topic + withAction:(FIRMessagingTopicAction)action + completion:(nullable FIRMessagingTopicOperationCompletion)completion; +- (void)resumeOperationsIfNeeded; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.m new file mode 100644 index 00000000..3a1afcbb --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.m @@ -0,0 +1,271 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPubSub.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" + +NSString *const kPendingTopicBatchActionKey = @"action"; +NSString *const kPendingTopicBatchTopicsKey = @"topics"; + +NSString *const kPendingBatchesEncodingKey = @"batches"; +NSString *const kPendingTopicsTimestampEncodingKey = @"ts"; + +#pragma mark - FIRMessagingTopicBatch + +@interface FIRMessagingTopicBatch () + +@property(nonatomic, strong, nonnull) + NSMutableDictionary<NSString *, NSMutableArray<FIRMessagingTopicOperationCompletion> *> + *topicHandlers; + +@end + +@implementation FIRMessagingTopicBatch + +- (instancetype)initWithAction:(FIRMessagingTopicAction)action { + if (self = [super init]) { + _action = action; + _topics = [NSMutableSet set]; + _topicHandlers = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeInteger:self.action forKey:kPendingTopicBatchActionKey]; + [aCoder encodeObject:self.topics forKey:kPendingTopicBatchTopicsKey]; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + // Ensure that our integer -> enum casting is safe + NSInteger actionRawValue = [aDecoder decodeIntegerForKey:kPendingTopicBatchActionKey]; + FIRMessagingTopicAction action = FIRMessagingTopicActionSubscribe; + if (actionRawValue == FIRMessagingTopicActionUnsubscribe) { + action = FIRMessagingTopicActionUnsubscribe; + } + + if (self = [self initWithAction:action]) { + _topics = [aDecoder + decodeObjectOfClasses:[NSSet setWithObjects:NSMutableSet.class, NSString.class, nil] + forKey:kPendingTopicBatchTopicsKey]; + _topicHandlers = [NSMutableDictionary dictionary]; + } + return self; +} + +@end + +#pragma mark - FIRMessagingPendingTopicsList + +@interface FIRMessagingPendingTopicsList () + +@property(nonatomic, readwrite, strong) NSDate *archiveDate; +@property(nonatomic, strong) NSMutableArray<FIRMessagingTopicBatch *> *topicBatches; + +@property(nonatomic, strong) FIRMessagingTopicBatch *currentBatch; +@property(nonatomic, strong) NSMutableSet<NSString *> *topicsInFlight; + +@end + +@implementation FIRMessagingPendingTopicsList + +- (instancetype)init { + if (self = [super init]) { + _topicBatches = [NSMutableArray array]; + _topicsInFlight = [NSMutableSet set]; + } + return self; +} + ++ (void)pruneTopicBatches:(NSMutableArray<FIRMessagingTopicBatch *> *)topicBatches { + // For now, just remove empty batches. In the future we can use this to make the subscriptions + // more efficient, by actually pruning topic actions that cancel each other out, for example. + for (NSInteger i = topicBatches.count - 1; i >= 0; i--) { + FIRMessagingTopicBatch *batch = topicBatches[i]; + if (batch.topics.count == 0) { + [topicBatches removeObjectAtIndex:i]; + } + } +} + +#pragma mark NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:[NSDate date] forKey:kPendingTopicsTimestampEncodingKey]; + [aCoder encodeObject:self.topicBatches forKey:kPendingBatchesEncodingKey]; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [self init]) { + _archiveDate = + [aDecoder decodeObjectOfClass:NSDate.class forKey:kPendingTopicsTimestampEncodingKey]; + _topicBatches = + [aDecoder decodeObjectOfClasses:[NSSet setWithObjects:NSMutableArray.class, + FIRMessagingTopicBatch.class, nil] + forKey:kPendingBatchesEncodingKey]; + if (_topicBatches) { + [FIRMessagingPendingTopicsList pruneTopicBatches:_topicBatches]; + } + _topicsInFlight = [NSMutableSet set]; + } + return self; +} + +#pragma mark Getters + +- (NSUInteger)numberOfBatches { + return self.topicBatches.count; +} + +#pragma mark Adding/Removing topics + +- (void)addOperationForTopic:(NSString *)topic + withAction:(FIRMessagingTopicAction)action + completion:(nullable FIRMessagingTopicOperationCompletion)completion { + FIRMessagingTopicBatch *lastBatch = nil; + @synchronized(self) { + lastBatch = self.topicBatches.lastObject; + if (!lastBatch || lastBatch.action != action) { + // There either was no last batch, or our last batch's action was not the same, so we have to + // create a new batch + lastBatch = [[FIRMessagingTopicBatch alloc] initWithAction:action]; + [self.topicBatches addObject:lastBatch]; + } + BOOL topicExistedBefore = ([lastBatch.topics member:topic] != nil); + if (!topicExistedBefore) { + [lastBatch.topics addObject:topic]; + [self.delegate pendingTopicsListDidUpdate:self]; + } + // Add the completion handler to the batch + if (completion) { + NSMutableArray *handlers = lastBatch.topicHandlers[topic]; + if (!handlers) { + handlers = [[NSMutableArray alloc] init]; + } + [handlers addObject:completion]; + lastBatch.topicHandlers[topic] = handlers; + } + if (!self.currentBatch) { + self.currentBatch = lastBatch; + } + // This may have been the first topic added, or was added to an ongoing batch + if (self.currentBatch == lastBatch && !topicExistedBefore) { + // Add this topic to our ongoing operations + FIRMessaging_WEAKIFY(self); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + FIRMessaging_STRONGIFY(self); + [self resumeOperationsIfNeeded]; + }); + } + } +} + +- (void)resumeOperationsIfNeeded { + @synchronized(self) { + // If current batch is not set, set it now + if (!self.currentBatch) { + self.currentBatch = self.topicBatches.firstObject; + } + if (self.currentBatch.topics.count == 0) { + return; + } + if (!self.delegate) { + FIRMessagingLoggerError(kFIRMessagingMessageCodePendingTopicsList000, + @"Attempted to update pending topics without a delegate"); + return; + } + if (![self.delegate pendingTopicsListCanRequestTopicUpdates:self]) { + return; + } + for (NSString *topic in self.currentBatch.topics) { + if ([self.topicsInFlight member:topic]) { + // This topic is already active, so skip + continue; + } + [self beginUpdateForCurrentBatchTopic:topic]; + } + } +} + +- (BOOL)subscriptionErrorIsRecoverable:(NSError *)error { + return [error.domain isEqualToString:NSURLErrorDomain]; +} + +- (void)beginUpdateForCurrentBatchTopic:(NSString *)topic { + @synchronized(self) { + [self.topicsInFlight addObject:topic]; + } + FIRMessaging_WEAKIFY(self); + [self.delegate + pendingTopicsList:self + requestedUpdateForTopic:topic + action:self.currentBatch.action + completion:^(NSError *error) { + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + FIRMessaging_STRONGIFY(self); + @synchronized(self) { + [self.topicsInFlight removeObject:topic]; + + BOOL recoverableError = [self subscriptionErrorIsRecoverable:error]; + if (!error || !recoverableError) { + // Notify our handlers and remove the topic from our batch + NSMutableArray *handlers = self.currentBatch.topicHandlers[topic]; + if (handlers.count) { + dispatch_async(dispatch_get_main_queue(), ^{ + for (FIRMessagingTopicOperationCompletion handler in handlers) { + handler(error); + } + [handlers removeAllObjects]; + }); + } + [self.currentBatch.topics removeObject:topic]; + [self.currentBatch.topicHandlers removeObjectForKey:topic]; + if (self.currentBatch.topics.count == 0) { + // All topic updates successfully finished in this batch, move on + // to the next batch + [self.topicBatches removeObject:self.currentBatch]; + self.currentBatch = nil; + } + [self.delegate pendingTopicsListDidUpdate:self]; + FIRMessaging_WEAKIFY(self); + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), + ^{ + FIRMessaging_STRONGIFY(self); + [self resumeOperationsIfNeeded]; + }); + } + } + }); + }]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h new file mode 100644 index 00000000..5a48e998 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@interface FIRMessagingPersistentSyncMessage : NSObject + +@property(nonatomic, readonly, strong) NSString *rmqID; +@property(nonatomic, readwrite, assign) BOOL apnsReceived; +@property(nonatomic, readwrite, assign) BOOL mcsReceived; +@property(nonatomic, readonly, assign) int64_t expirationTime; + +- (instancetype)initWithRMQID:(NSString *)rmqID expirationTime:(int64_t)expirationTime; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.m new file mode 100644 index 00000000..db032a91 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.m @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" + +@interface FIRMessagingPersistentSyncMessage () + +@property(nonatomic, readwrite, strong) NSString *rmqID; +@property(nonatomic, readwrite, assign) int64_t expirationTime; + +@end + +@implementation FIRMessagingPersistentSyncMessage + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithRMQID:(NSString *)rmqID expirationTime:(int64_t)expirationTime { + self = [super init]; + if (self) { + _rmqID = [rmqID copy]; + _expirationTime = expirationTime; + } + return self; +} + +- (NSString *)description { + NSString *classDescription = NSStringFromClass([self class]); + NSDate *date = [NSDate dateWithTimeIntervalSince1970:self.expirationTime]; + return + [NSString stringWithFormat:@"%@: (rmqID: %@, apns: %d, mcs: %d, expiry: %@", classDescription, + self.rmqID, self.mcsReceived, self.apnsReceived, date]; +} + +- (NSString *)debugDescription { + return [self description]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSub.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSub.h new file mode 100644 index 00000000..f0f541e6 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSub.h @@ -0,0 +1,171 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessaging.h> + +NS_ASSUME_NONNULL_BEGIN + +@class FIRMessagingClient; +@class FIRMessagingPubSubCache; + +/** + * FIRMessagingPubSub provides a publish-subscribe model for sending FIRMessaging topic messages. + * + * An app can subscribe to different topics defined by the + * developer. The app server can then send messages to the subscribed devices + * without having to maintain topic-subscribers mapping. Topics do not + * need to be explicitly created before subscribing or publishing—they + * are automatically created when publishing or subscribing. + * + * Messages published to the topic will be received as regular FIRMessaging messages + * with `"from"` set to `"/topics/myTopic"`. + * + * Only topic names that match the pattern `"/topics/[a-zA-Z0-9-_.~%]{1,900}"` + * are allowed for subscribing and publishing. + */ +@interface FIRMessagingPubSub : NSObject + +@property(nonatomic, readonly, strong) FIRMessagingPubSubCache *cache; +@property(nonatomic, readonly, strong) FIRMessagingClient *client; + +/** + * Initializes an instance of FIRMessagingPubSub. + * + * @return An instance of FIRMessagingPubSub. + */ +- (instancetype)initWithClient:(FIRMessagingClient *)client NS_DESIGNATED_INITIALIZER; + +/** + * Subscribes an app instance to a topic, enabling it to receive messages + * sent to that topic. + * + * This is an asynchronous call. If subscription fails, FIRMessaging + * invokes the completion callback with the appropriate error. + * + * @see FIRMessagingPubSub unsubscribeWithToken:topic:handler: + * + * @param token The registration token as received from the InstanceID + * library for a given `authorizedEntity` and "gcm" scope. + * @param topic The topic to subscribe to. Should be of the form + * `"/topics/<topic-name>"`. + * @param options Unused parameter, please pass nil or empty dictionary. + * @param handler The callback handler invoked when the subscribe call + * ends. In case of success, a nil error is returned. Otherwise, + * an appropriate error object is returned. + * @discussion This method is thread-safe. However, it is not guaranteed to + * return on the main thread. + */ +- (void)subscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(nullable NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler; + +/** + * Unsubscribes an app instance from a topic, stopping it from receiving + * any further messages sent to that topic. + * + * This is an asynchronous call. If the attempt to unsubscribe fails, + * we invoke the `completion` callback passed in with an appropriate error. + * + * @param token The token used to subscribe to this topic. + * @param topic The topic to unsubscribe from. Should be of the form + * `"/topics/<topic-name>"`. + * @param options Unused parameter, please pass nil or empty dictionary. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + * @discussion This method is thread-safe. However, it is not guaranteed to + * return on the main thread. + */ +- (void)unsubscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(nullable NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler; + +/** + * Asynchronously subscribe to the topic. Adds to the pending list of topic operations. + * Retry in case of failures. This makes a repeated attempt to subscribe to the topic + * as compared to the `subscribe` method above which tries once. + * + * @param topic The topic name to subscribe to. Should be of the form `"/topics/<topic-name>"`. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)subscribeToTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler; + +/** + * Asynchronously unsubscribe from the topic. Adds to the pending list of topic operations. + * Retry in case of failures. This makes a repeated attempt to unsubscribe from the topic + * as compared to the `unsubscribe` method above which tries once. + * + * @param topic The topic name to unsubscribe from. Should be of the form `"/topics/<topic-name>"`. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)unsubscribeFromTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler; + +/** + * Schedule subscriptions sync. + * + * @param immediately YES if the sync should be scheduled immediately else NO if we can delay + * the sync. + */ +- (void)scheduleSync:(BOOL)immediately; + +/** + * Adds the "/topics/" prefix to the topic. + * + * @param topic The topic to add the prefix to. + * + * @return The new topic name with the "/topics/" prefix added. + */ ++ (NSString *)addPrefixToTopic:(NSString *)topic; + +/** + * Removes the "/topics/" prefix from the topic. + * + * @param topic The topic to remove the prefix from. + * + * @return The new topic name with the "/topics/" prefix removed. + */ + ++ (NSString *)removePrefixFromTopic:(NSString *)topic; + +/** + * Check if the topic name has "/topics/" prefix. + * + * @param topic The topic name to verify. + * + * @return YES if the topic name has "/topics/" prefix else NO. + */ ++ (BOOL)hasTopicsPrefix:(NSString *)topic; + +/** + * Check if it's a valid topic name. This includes "/topics/" prefix in the topic name. + * + * @param topic The topic name to verify. + * + * @return YES if the topic name satisfies the regex "/topics/[a-zA-Z0-9-_.~%]{1,900}". + */ ++ (BOOL)isValidTopicWithPrefix:(NSString *)topic; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSub.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSub.m new file mode 100644 index 00000000..15d26e68 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSub.m @@ -0,0 +1,295 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingPubSub.h" + +#import <FirebaseMessaging/FIRMessaging.h> +#import "GoogleUtilities/Environment/Private/GULSecureCoding.h" +#import "GoogleUtilities/UserDefaults/Private/GULUserDefaults.h" + +#import "FirebaseMessaging/Sources/FIRMessagingClient.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPendingTopicsList.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" +#import "FirebaseMessaging/Sources/NSDictionary+FIRMessaging.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" + +static NSString *const kPendingSubscriptionsListKey = + @"com.firebase.messaging.pending-subscriptions"; + +@interface FIRMessagingPubSub () <FIRMessagingPendingTopicsListDelegate> + +@property(nonatomic, readwrite, strong) FIRMessagingPendingTopicsList *pendingTopicUpdates; +@property(nonatomic, readwrite, strong) FIRMessagingClient *client; + +@end + +@implementation FIRMessagingPubSub + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); + // Need this to disable an Xcode warning. + return [self initWithClient:nil]; +} + +- (instancetype)initWithClient:(FIRMessagingClient *)client { + self = [super init]; + if (self) { + _client = client; + [self restorePendingTopicsList]; + } + return self; +} + +- (void)subscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler { + if (!self.client) { + handler([NSError + messagingErrorWithCode:kFIRMessagingErrorCodePubSubClientNotSetup + failureReason:@"Firebase Messaging Client does not exist. Firebase Messaging was " + @"not setup property and subscription failed."]); + return; + } + + token = [token copy]; + topic = [topic copy]; + + if (![options count]) { + options = @{}; + } + + if (![[self class] isValidTopicWithPrefix:topic]) { + NSString *failureReason = + [NSString stringWithFormat:@"Invalid subscription topic :'%@'", topic]; + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub000, @"%@", failureReason); + handler([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName + failureReason:failureReason]); + return; + } + + if (![self verifyPubSubOptions:options]) { + // we do not want to quit even if options have some invalid values. + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub001, + @"Invalid options passed to FIRMessagingPubSub with non-string keys or " + "values."); + } + // copy the dictionary would trim non-string keys or values if any. + options = [options fcm_trimNonStringValues]; + + [self.client updateSubscriptionWithToken:token + topic:topic + options:options + shouldDelete:NO + handler:^void(NSError *error) { + handler(error); + }]; +} + +- (void)unsubscribeWithToken:(NSString *)token + topic:(NSString *)topic + options:(NSDictionary *)options + handler:(FIRMessagingTopicOperationCompletion)handler { + if (!self.client) { + handler([NSError + messagingErrorWithCode:kFIRMessagingErrorCodePubSubClientNotSetup + failureReason:@"Firebase Messaging Client does not exist. Firebase Messaging was " + @"not setup property and subscription failed."]); + return; + } + token = [token copy]; + topic = [topic copy]; + if (![options count]) { + options = @{}; + } + + if (![[self class] isValidTopicWithPrefix:topic]) { + NSString *failureReason = + [NSString stringWithFormat:@"Invalid topic name : '%@' for unsubscription.", topic]; + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSub002, @"%@", failureReason); + handler([NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidTopicName + failureReason:failureReason]); + return; + } + if (![self verifyPubSubOptions:options]) { + // we do not want to quit even if options have some invalid values. + FIRMessagingLoggerError( + kFIRMessagingMessageCodePubSub003, + @"Invalid options passed to FIRMessagingPubSub with non-string keys or values."); + } + // copy the dictionary would trim non-string keys or values if any. + options = [options fcm_trimNonStringValues]; + + [self.client updateSubscriptionWithToken:token + topic:topic + options:options + shouldDelete:YES + handler:^void(NSError *error) { + handler(error); + }]; +} + +- (void)subscribeToTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler { + [self.pendingTopicUpdates addOperationForTopic:topic + withAction:FIRMessagingTopicActionSubscribe + completion:handler]; +} + +- (void)unsubscribeFromTopic:(NSString *)topic + handler:(nullable FIRMessagingTopicOperationCompletion)handler { + [self.pendingTopicUpdates addOperationForTopic:topic + withAction:FIRMessagingTopicActionUnsubscribe + completion:handler]; +} + +- (void)scheduleSync:(BOOL)immediately { + NSString *fcmToken = [[FIRMessaging messaging] defaultFcmToken]; + if (fcmToken.length) { + [self.pendingTopicUpdates resumeOperationsIfNeeded]; + } +} + +#pragma mark - FIRMessagingPendingTopicsListDelegate + +- (void)pendingTopicsList:(FIRMessagingPendingTopicsList *)list + requestedUpdateForTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + completion:(FIRMessagingTopicOperationCompletion)completion { + NSString *fcmToken = [[FIRMessaging messaging] defaultFcmToken]; + if (action == FIRMessagingTopicActionSubscribe) { + [self subscribeWithToken:fcmToken topic:topic options:nil handler:completion]; + } else { + [self unsubscribeWithToken:fcmToken topic:topic options:nil handler:completion]; + } +} + +- (void)pendingTopicsListDidUpdate:(FIRMessagingPendingTopicsList *)list { + [self archivePendingTopicsList:list]; +} + +- (BOOL)pendingTopicsListCanRequestTopicUpdates:(FIRMessagingPendingTopicsList *)list { + NSString *fcmToken = [[FIRMessaging messaging] defaultFcmToken]; + return (fcmToken.length > 0); +} + +#pragma mark - Storing Pending Topics + +- (void)archivePendingTopicsList:(FIRMessagingPendingTopicsList *)topicsList { + GULUserDefaults *defaults = [GULUserDefaults standardUserDefaults]; + NSError *error; + NSData *pendingData = [GULSecureCoding archivedDataWithRootObject:topicsList error:&error]; + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSubArchiveError, + @"Failed to archive topic list data %@", error); + return; + } + [defaults setObject:pendingData forKey:kPendingSubscriptionsListKey]; + [defaults synchronize]; +} + +- (void)restorePendingTopicsList { + GULUserDefaults *defaults = [GULUserDefaults standardUserDefaults]; + NSData *pendingData = [defaults objectForKey:kPendingSubscriptionsListKey]; + FIRMessagingPendingTopicsList *subscriptions; + if (pendingData) { + NSError *error; + subscriptions = [GULSecureCoding + unarchivedObjectOfClasses:[NSSet setWithObjects:FIRMessagingPendingTopicsList.class, nil] + fromData:pendingData + error:&error]; + if (error) { + FIRMessagingLoggerError(kFIRMessagingMessageCodePubSubUnarchiveError, + @"Failed to unarchive topic list data %@", error); + } + } + if (subscriptions) { + self.pendingTopicUpdates = subscriptions; + } else { + self.pendingTopicUpdates = [[FIRMessagingPendingTopicsList alloc] init]; + } + self.pendingTopicUpdates.delegate = self; +} + +#pragma mark - Private Helpers + +- (BOOL)verifyPubSubOptions:(NSDictionary *)options { + return ![options fcm_hasNonStringKeysOrValues]; +} + +#pragma mark - Topic Name Helpers + +static NSString *const kTopicsPrefix = @"/topics/"; +static NSString *const kTopicRegexPattern = @"/topics/([a-zA-Z0-9-_.~%]+)"; + ++ (NSString *)addPrefixToTopic:(NSString *)topic { + if (![self hasTopicsPrefix:topic]) { + return [NSString stringWithFormat:@"%@%@", kTopicsPrefix, topic]; + } else { + return [topic copy]; + } +} + ++ (NSString *)removePrefixFromTopic:(NSString *)topic { + if ([self hasTopicsPrefix:topic]) { + return [topic substringFromIndex:kTopicsPrefix.length]; + } else { + return [topic copy]; + } +} + ++ (BOOL)hasTopicsPrefix:(NSString *)topic { + return [topic hasPrefix:kTopicsPrefix]; +} + +/** + * Returns a regular expression for matching a topic sender. + * + * @return The topic matching regular expression + */ ++ (NSRegularExpression *)topicRegex { + // Since this is a static regex pattern, we only only need to declare it once. + static NSRegularExpression *topicRegex; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSError *error; + topicRegex = + [NSRegularExpression regularExpressionWithPattern:kTopicRegexPattern + options:NSRegularExpressionAnchorsMatchLines + error:&error]; + }); + return topicRegex; +} + +/** + * Gets the class describing occurences of topic names and sender IDs in the sender. + * + * @param topic The topic expression used to generate a pubsub topic + * + * @return Representation of captured subexpressions in topic regular expression + */ ++ (BOOL)isValidTopicWithPrefix:(NSString *)topic { + NSRange topicRange = NSMakeRange(0, topic.length); + NSRange regexMatchRange = [[self topicRegex] rangeOfFirstMatchInString:topic + options:NSMatchingAnchored + range:topicRange]; + return NSEqualRanges(topicRange, regexMatchRange); +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.h new file mode 100644 index 00000000..0ba31d0e --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingTopicOperation.h" + +@interface FIRMessagingPubSubRegistrar : NSObject + +/** + * Stops all the subscription requests going on in parallel. This would + * invalidate all the handlers associated with the subscription requests. + */ +- (void)stopAllSubscriptionRequests; + +/** + * Update subscription status for a given topic with FIRMessaging's backend. + * + * @param topic The topic to subscribe to. + * @param token The registration token to be used. + * @param options The options to be passed in during subscription request. + * @param shouldDelete NO if the subscription is being added else YES if being + * removed. + * @param handler The handler invoked once the update subscription request + * finishes. + */ +- (void)updateSubscriptionToTopic:(NSString *)topic + withToken:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.m new file mode 100644 index 00000000..fdd965d6 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.m @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingPubSubRegistrar.h" +#import "FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" + +@interface FIRMessagingPubSubRegistrar () + +@property(nonatomic, readonly, strong) NSOperationQueue *topicOperations; +// Common errors, instantiated, to avoid generating multiple copies +@property(nonatomic, readwrite, strong) NSError *operationInProgressError; + +@end + +@implementation FIRMessagingPubSubRegistrar + +- (instancetype)init { + self = [super init]; + if (self) { + _topicOperations = [[NSOperationQueue alloc] init]; + // Do 10 topic operations at a time; it's enough to keep the TCP connection to the host alive, + // saving hundreds of milliseconds on each request (compared to a serial queue). + _topicOperations.maxConcurrentOperationCount = 10; + } + return self; +} + +- (void)stopAllSubscriptionRequests { + [self.topicOperations cancelAllOperations]; +} + +- (void)updateSubscriptionToTopic:(NSString *)topic + withToken:(NSString *)token + options:(NSDictionary *)options + shouldDelete:(BOOL)shouldDelete + handler:(FIRMessagingTopicOperationCompletion)handler { + FIRMessagingTopicAction action = FIRMessagingTopicActionSubscribe; + if (shouldDelete) { + action = FIRMessagingTopicActionUnsubscribe; + } + FIRMessagingTopicOperation *operation = + [[FIRMessagingTopicOperation alloc] initWithTopic:topic + action:action + token:token + options:options + completion:handler]; + [self.topicOperations addOperation:operation]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingReceiver.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingReceiver.h new file mode 100644 index 00000000..9d784228 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingReceiver.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessaging.h> +#import "FirebaseMessaging/Sources/FIRMessagingDataMessageManager.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRMessagingReceiver; +@protocol FIRMessagingReceiverDelegate <NSObject> + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void)receiver:(FIRMessagingReceiver *)receiver + receivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage; +#pragma clang diagnostic pop + +@end + +@interface FIRMessagingReceiver : NSObject <FIRMessagingDataMessageManagerDelegate> + +@property(nonatomic, weak, nullable) id<FIRMessagingReceiverDelegate> delegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingReceiver.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingReceiver.m new file mode 100644 index 00000000..1c995d58 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingReceiver.m @@ -0,0 +1,104 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingReceiver.h" + +#import <FirebaseMessaging/FIRMessaging.h> + +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" + +static NSString *const kUpstreamMessageIDUserInfoKey = @"messageID"; +static NSString *const kUpstreamErrorUserInfoKey = @"error"; + +static int downstreamMessageID = 0; + +@implementation FIRMessagingReceiver + +#pragma mark - FIRMessagingDataMessageManager protocol + +- (void)didReceiveMessage:(NSDictionary *)message withIdentifier:(nullable NSString *)messageID { + if (![messageID length]) { + messageID = [[self class] nextMessageID]; + } + + [self handleDirectChannelMessage:message withIdentifier:messageID]; +} + +- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error { + NSNotification *notification; + if (error) { + NSDictionary *userInfo = + @{kUpstreamMessageIDUserInfoKey : [messageID copy], kUpstreamErrorUserInfoKey : error}; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + notification = [NSNotification notificationWithName:FIRMessagingSendErrorNotification + object:nil + userInfo:userInfo]; +#pragma clang diagnostic pop + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver000, + @"Fail to send upstream message: %@ error: %@", messageID, error); + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver001, @"Will send upstream message: %@", + messageID); + } +} + +- (void)didSendDataMessageWithID:(NSString *)messageID { + // invoke the callbacks asynchronously + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver002, @"Did send upstream message: %@", + messageID); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSNotification *notification = + [NSNotification notificationWithName:FIRMessagingSendSuccessNotification + object:nil + userInfo:@{kUpstreamMessageIDUserInfoKey : [messageID copy]}]; +#pragma clang diagnostic pop + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; +} + +- (void)didDeleteMessagesOnServer { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeReceiver003, + @"Will send deleted messages notification"); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSNotification *notification = + [NSNotification notificationWithName:FIRMessagingMessagesDeletedNotification object:nil]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP]; +} + +#pragma mark - Private Helpers +- (void)handleDirectChannelMessage:(NSDictionary *)message withIdentifier:(NSString *)messageID { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + FIRMessagingRemoteMessage *wrappedMessage = [[FIRMessagingRemoteMessage alloc] init]; + wrappedMessage.appData = [message copy]; + wrappedMessage.messageID = messageID; + [self.delegate receiver:self receivedRemoteMessage:wrappedMessage]; +#pragma clang diagnostic pop +} + ++ (NSString *)nextMessageID { + @synchronized(self) { + ++downstreamMessageID; + return [NSString stringWithFormat:@"gcm-%d", downstreamMessageID]; + } +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.h new file mode 100644 index 00000000..f0010b3b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +/** + * Swizzle remote-notification callbacks to invoke FIRMessaging methods + * before calling original implementations. + */ +@interface FIRMessagingRemoteNotificationsProxy : NSObject + +/** + * Checks the `FirebaseAppDelegateProxyEnabled` key in the App's Info.plist. If the key is + * missing or incorrectly formatted, returns `YES`. + * + * @return YES if the Application Delegate and User Notification Center methods can be swizzled. + * Otherwise, returns NO. + */ ++ (BOOL)canSwizzleMethods; + +/** + * A shared instance of `FIRMessagingRemoteNotificationsProxy` + */ ++ (instancetype)sharedProxy; + +/** + * Swizzles Application Delegate's remote-notification callbacks and User Notification Center + * delegate callback, and invokes the original selectors once done. + */ +- (void)swizzleMethodsIfPossible; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.m new file mode 100644 index 00000000..39f0a920 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.m @@ -0,0 +1,591 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.h" + +#import <objc/runtime.h> + +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/FIRMessaging_Private.h" +#import "GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h" + +static void *UserNotificationObserverContext = &UserNotificationObserverContext; + +static NSString *kUserNotificationWillPresentSelectorString = + @"userNotificationCenter:willPresentNotification:withCompletionHandler:"; +static NSString *kUserNotificationDidReceiveResponseSelectorString = + @"userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:"; + +@interface FIRMessagingRemoteNotificationsProxy () <GULApplicationDelegate> + +@property(strong, nonatomic) NSMutableDictionary<NSString *, NSValue *> *originalAppDelegateImps; +@property(strong, nonatomic) NSMutableDictionary<NSString *, NSArray *> *swizzledSelectorsByClass; + +@property(nonatomic) BOOL didSwizzleMethods; + +@property(nonatomic) BOOL hasSwizzledUserNotificationDelegate; +@property(nonatomic) BOOL isObservingUserNotificationDelegateChanges; + +@property(strong, nonatomic) id userNotificationCenter; +@property(strong, nonatomic) id currentUserNotificationCenterDelegate; + +@property(strong, nonatomic) GULAppDelegateInterceptorID appDelegateInterceptorID; + +@end + +@implementation FIRMessagingRemoteNotificationsProxy + ++ (BOOL)canSwizzleMethods { + return [GULAppDelegateSwizzler isAppDelegateProxyEnabled]; +} + ++ (instancetype)sharedProxy { + static FIRMessagingRemoteNotificationsProxy *proxy; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + proxy = [[FIRMessagingRemoteNotificationsProxy alloc] init]; + }); + return proxy; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _originalAppDelegateImps = [[NSMutableDictionary alloc] init]; + _swizzledSelectorsByClass = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)dealloc { + [self unswizzleAllMethods]; + self.swizzledSelectorsByClass = nil; + [self.originalAppDelegateImps removeAllObjects]; + self.originalAppDelegateImps = nil; + [self removeUserNotificationCenterDelegateObserver]; +} + +- (void)swizzleMethodsIfPossible { + // Already swizzled. + if (self.didSwizzleMethods) { + return; + } + + [GULAppDelegateSwizzler proxyOriginalDelegateIncludingAPNSMethods]; + self.appDelegateInterceptorID = [GULAppDelegateSwizzler registerAppDelegateInterceptor:self]; + + // Add KVO listener on [UNUserNotificationCenter currentNotificationCenter]'s delegate property + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + if (notificationCenterClass) { + // We are linked against iOS 10 SDK or above + id notificationCenter = FIRMessagingPropertyNameFromObject( + notificationCenterClass, @"currentNotificationCenter", notificationCenterClass); + if (notificationCenter) { + [self listenForDelegateChangesInUserNotificationCenter:notificationCenter]; + } + } + + self.didSwizzleMethods = YES; +} + +- (void)unswizzleAllMethods { + if (self.appDelegateInterceptorID) { + [GULAppDelegateSwizzler unregisterAppDelegateInterceptorWithID:self.appDelegateInterceptorID]; + } + + for (NSString *className in self.swizzledSelectorsByClass) { + Class klass = NSClassFromString(className); + NSArray *selectorStrings = self.swizzledSelectorsByClass[className]; + for (NSString *selectorString in selectorStrings) { + SEL selector = NSSelectorFromString(selectorString); + [self unswizzleSelector:selector inClass:klass]; + } + } + [self.swizzledSelectorsByClass removeAllObjects]; +} + +- (void)listenForDelegateChangesInUserNotificationCenter:(id)notificationCenter { + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + if (![notificationCenter isKindOfClass:notificationCenterClass]) { + return; + } + id delegate = FIRMessagingPropertyNameFromObject(notificationCenter, @"delegate", nil); + Protocol *delegateProtocol = NSProtocolFromString(@"UNUserNotificationCenterDelegate"); + if ([delegate conformsToProtocol:delegateProtocol]) { + // Swizzle this object now, if available + [self swizzleUserNotificationCenterDelegate:delegate]; + } + // Add KVO observer for "delegate" keyPath for future changes + [self addDelegateObserverToUserNotificationCenter:notificationCenter]; +} + +#pragma mark - UNNotificationCenter Swizzling + +- (void)swizzleUserNotificationCenterDelegate:(id _Nonnull)delegate { + if (self.currentUserNotificationCenterDelegate == delegate) { + // Via pointer-check, compare if we have already swizzled this item. + return; + } + Protocol *userNotificationCenterProtocol = + NSProtocolFromString(@"UNUserNotificationCenterDelegate"); + if ([delegate conformsToProtocol:userNotificationCenterProtocol]) { + SEL willPresentNotificationSelector = + NSSelectorFromString(kUserNotificationWillPresentSelectorString); + // Swizzle the optional method + // "userNotificationCenter:willPresentNotification:withCompletionHandler:", if it is + // implemented. Do not swizzle otherwise, as an implementation *will* be created, which will + // fool iOS into thinking that this method is implemented, and therefore not send notifications + // to the fallback method in the app delegate + // "application:didReceiveRemoteNotification:fetchCompletionHandler:". + if ([delegate respondsToSelector:willPresentNotificationSelector]) { + [self swizzleSelector:willPresentNotificationSelector + inClass:[delegate class] + withImplementation:(IMP)FCMSwizzleWillPresentNotificationWithHandler + inProtocol:userNotificationCenterProtocol]; + } + SEL didReceiveNotificationResponseSelector = + NSSelectorFromString(kUserNotificationDidReceiveResponseSelectorString); + if ([delegate respondsToSelector:didReceiveNotificationResponseSelector]) { + [self swizzleSelector:didReceiveNotificationResponseSelector + inClass:[delegate class] + withImplementation:(IMP)FCMSwizzleDidReceiveNotificationResponseWithHandler + inProtocol:userNotificationCenterProtocol]; + } + self.currentUserNotificationCenterDelegate = delegate; + self.hasSwizzledUserNotificationDelegate = YES; + } +} + +- (void)unswizzleUserNotificationCenterDelegate:(id _Nonnull)delegate { + if (self.currentUserNotificationCenterDelegate != delegate) { + // We aren't swizzling this delegate, so don't do anything. + return; + } + SEL willPresentNotificationSelector = + NSSelectorFromString(kUserNotificationWillPresentSelectorString); + // Call unswizzle methods, even if the method was not implemented (it will fail gracefully). + [self unswizzleSelector:willPresentNotificationSelector + inClass:[self.currentUserNotificationCenterDelegate class]]; + SEL didReceiveNotificationResponseSelector = + NSSelectorFromString(kUserNotificationDidReceiveResponseSelectorString); + [self unswizzleSelector:didReceiveNotificationResponseSelector + inClass:[self.currentUserNotificationCenterDelegate class]]; + self.currentUserNotificationCenterDelegate = nil; + self.hasSwizzledUserNotificationDelegate = NO; +} + +#pragma mark - KVO for UNUserNotificationCenter + +- (void)addDelegateObserverToUserNotificationCenter:(id)userNotificationCenter { + [self removeUserNotificationCenterDelegateObserver]; + @try { + [userNotificationCenter addObserver:self + forKeyPath:NSStringFromSelector(@selector(delegate)) + options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld + context:UserNotificationObserverContext]; + self.userNotificationCenter = userNotificationCenter; + self.isObservingUserNotificationDelegateChanges = YES; + } @catch (NSException *exception) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxy000, + @"Encountered exception trying to add a KVO observer for " + @"UNUserNotificationCenter's 'delegate' property: %@", + exception); + } @finally { + } +} + +- (void)removeUserNotificationCenterDelegateObserver { + if (!self.userNotificationCenter) { + return; + } + @try { + [self.userNotificationCenter removeObserver:self + forKeyPath:NSStringFromSelector(@selector(delegate)) + context:UserNotificationObserverContext]; + self.userNotificationCenter = nil; + self.isObservingUserNotificationDelegateChanges = NO; + } @catch (NSException *exception) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxy001, + @"Encountered exception trying to remove a KVO observer for " + @"UNUserNotificationCenter's 'delegate' property: %@", + exception); + } @finally { + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary<NSKeyValueChangeKey, id> *)change + context:(void *)context { + if (context == UserNotificationObserverContext) { + if ([keyPath isEqualToString:NSStringFromSelector(@selector(delegate))]) { + id oldDelegate = change[NSKeyValueChangeOldKey]; + if (oldDelegate && oldDelegate != [NSNull null]) { + [self unswizzleUserNotificationCenterDelegate:oldDelegate]; + } + id newDelegate = change[NSKeyValueChangeNewKey]; + if (newDelegate && newDelegate != [NSNull null]) { + [self swizzleUserNotificationCenterDelegate:newDelegate]; + } + } + } else { + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + } +} + +#pragma mark - NSProxy methods + +- (void)saveOriginalImplementation:(IMP)imp forSelector:(SEL)selector { + if (imp && selector) { + NSValue *IMPValue = [NSValue valueWithPointer:imp]; + NSString *selectorString = NSStringFromSelector(selector); + self.originalAppDelegateImps[selectorString] = IMPValue; + } +} + +- (IMP)originalImplementationForSelector:(SEL)selector { + NSString *selectorString = NSStringFromSelector(selector); + NSValue *implementationValue = self.originalAppDelegateImps[selectorString]; + if (!implementationValue) { + return nil; + } + + IMP imp; + [implementationValue getValue:&imp]; + return imp; +} + +- (void)trackSwizzledSelector:(SEL)selector ofClass:(Class)klass { + NSString *className = NSStringFromClass(klass); + NSString *selectorString = NSStringFromSelector(selector); + NSArray *selectors = self.swizzledSelectorsByClass[selectorString]; + if (selectors) { + selectors = [selectors arrayByAddingObject:selectorString]; + } else { + selectors = @[ selectorString ]; + } + self.swizzledSelectorsByClass[className] = selectors; +} + +- (void)removeImplementationForSelector:(SEL)selector { + NSString *selectorString = NSStringFromSelector(selector); + [self.originalAppDelegateImps removeObjectForKey:selectorString]; +} + +- (void)swizzleSelector:(SEL)originalSelector + inClass:(Class)klass + withImplementation:(IMP)swizzledImplementation + inProtocol:(Protocol *)protocol { + Method originalMethod = class_getInstanceMethod(klass, originalSelector); + + if (originalMethod) { + // This class implements this method, so replace the original implementation + // with our new implementation and save the old implementation. + + IMP originalMethodImplementation = + method_setImplementation(originalMethod, swizzledImplementation); + + IMP nonexistantMethodImplementation = [self nonExistantMethodImplementationForClass:klass]; + + if (originalMethodImplementation && + originalMethodImplementation != nonexistantMethodImplementation && + originalMethodImplementation != swizzledImplementation) { + [self saveOriginalImplementation:originalMethodImplementation forSelector:originalSelector]; + } + } else { + // The class doesn't have this method, so add our swizzled implementation as the + // original implementation of the original method. + struct objc_method_description methodDescription = + protocol_getMethodDescription(protocol, originalSelector, NO, YES); + + BOOL methodAdded = + class_addMethod(klass, originalSelector, swizzledImplementation, methodDescription.types); + if (!methodAdded) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxyMethodNotAdded, + @"Could not add method for %@ to class %@", + NSStringFromSelector(originalSelector), NSStringFromClass(klass)); + } + } + [self trackSwizzledSelector:originalSelector ofClass:klass]; +} + +- (void)unswizzleSelector:(SEL)selector inClass:(Class)klass { + Method swizzledMethod = class_getInstanceMethod(klass, selector); + if (!swizzledMethod) { + // This class doesn't seem to have this selector as an instance method? Bail out. + return; + } + + IMP originalImp = [self originalImplementationForSelector:selector]; + if (originalImp) { + // Restore the original implementation as the current implementation + method_setImplementation(swizzledMethod, originalImp); + [self removeImplementationForSelector:selector]; + } else { + // This class originally did not have an implementation for this selector. + + // We can't actually remove methods in Objective C 2.0, but we could set + // its method to something non-existent. This should give us the same + // behavior as if the method was not implemented. + // See: http://stackoverflow.com/a/8276527/9849 + + IMP nonExistantMethodImplementation = [self nonExistantMethodImplementationForClass:klass]; + method_setImplementation(swizzledMethod, nonExistantMethodImplementation); + } +} + +#pragma mark - Reflection Helpers + +// This is useful to generate from a stable, "known missing" selector, as the IMP can be compared +// in case we are setting an implementation for a class that was previously "unswizzled" into a +// non-existant implementation. +- (IMP)nonExistantMethodImplementationForClass:(Class)klass { + SEL nonExistantSelector = NSSelectorFromString(@"aNonExistantMethod"); + IMP nonExistantMethodImplementation = class_getMethodImplementation(klass, nonExistantSelector); + return nonExistantMethodImplementation; +} + +// A safe, non-leaky way return a property object by its name +id FIRMessagingPropertyNameFromObject(id object, NSString *propertyName, Class klass) { + SEL selector = NSSelectorFromString(propertyName); + if (![object respondsToSelector:selector]) { + return nil; + } + if (!klass) { + klass = [NSObject class]; + } + // Suppress clang warning about leaks in performSelector + // The alternative way to perform this is to invoke + // the method as a block (see http://stackoverflow.com/a/20058585), + // but this approach sometimes returns incomplete objects. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id property = [object performSelector:selector]; +#pragma clang diagnostic pop + if (![property isKindOfClass:klass]) { + return nil; + } + return property; +} + +#pragma mark - GULApplicationDelegate +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +- (void)application:(GULApplication *)application + didReceiveRemoteNotification:(NSDictionary *)userInfo { + [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; +} +#pragma clang diagnostic pop + +#if TARGET_OS_IOS || TARGET_OS_TV +- (void)application:(UIApplication *)application + didReceiveRemoteNotification:(NSDictionary *)userInfo + fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { + [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; +} + +- (void)application:(UIApplication *)application + didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + // Log the fact that we failed to register for remote notifications + FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxyAPNSFailed, + @"Error in " + @"application:didFailToRegisterForRemoteNotificationsWithError: %@", + error.localizedDescription); +} +#endif + +- (void)application:(GULApplication *)application + didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + [FIRMessaging messaging].APNSToken = deviceToken; +} + +#pragma mark - Swizzled Methods + +/** + * Swizzle the notification handler for iOS 10+ devices. + * Signature of original handler is as below: + * - (void)userNotificationCenter:(UNUserNotificationCenter *)center + * willPresentNotification:(UNNotification *)notification + * withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler + * In order to make FCM SDK compile and compatible with iOS SDKs before iOS 10, hide the + * parameter types from the swizzling implementation. + */ +static void FCMSwizzleWillPresentNotificationWithHandler( + id self, SEL cmd, id center, id notification, void (^handler)(NSUInteger)) { + FIRMessagingRemoteNotificationsProxy *proxy = [FIRMessagingRemoteNotificationsProxy sharedProxy]; + IMP originalImp = [proxy originalImplementationForSelector:cmd]; + + void (^callOriginalMethodIfAvailable)(void) = ^{ + if (originalImp) { + ((void (*)(id, SEL, id, id, void (^)(NSUInteger)))originalImp)(self, cmd, center, + notification, handler); + } + return; + }; + + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + Class notificationClass = NSClassFromString(@"UNNotification"); + if (!notificationCenterClass || !notificationClass) { + // Can't find UserNotifications framework. Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + } + + if (!center || ![center isKindOfClass:[notificationCenterClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!notification || ![notification isKindOfClass:[notificationClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!handler) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + // Attempt to access the user info + id notificationUserInfo = FIRMessagingUserInfoFromNotification(notification); + + if (!notificationUserInfo) { + // Could not access notification.request.content.userInfo. + callOriginalMethodIfAvailable(); + return; + } + + [[FIRMessaging messaging] appDidReceiveMessage:notificationUserInfo]; + // Execute the original implementation. + callOriginalMethodIfAvailable(); +} + +/** + * Swizzle the notification handler for iOS 10+ devices. + * Signature of original handler is as below: + * - (void)userNotificationCenter:(UNUserNotificationCenter *)center + * didReceiveNotificationResponse:(UNNotificationResponse *)response + * withCompletionHandler:(void (^)(void))completionHandler + * In order to make FCM SDK compile and compatible with iOS SDKs before iOS 10, hide the + * parameter types from the swizzling implementation. + */ +static void FCMSwizzleDidReceiveNotificationResponseWithHandler( + id self, SEL cmd, id center, id response, void (^handler)(void)) { + FIRMessagingRemoteNotificationsProxy *proxy = [FIRMessagingRemoteNotificationsProxy sharedProxy]; + IMP originalImp = [proxy originalImplementationForSelector:cmd]; + + void (^callOriginalMethodIfAvailable)(void) = ^{ + if (originalImp) { + ((void (*)(id, SEL, id, id, void (^)(void)))originalImp)(self, cmd, center, response, + handler); + } + return; + }; + + Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter"); + Class responseClass = NSClassFromString(@"UNNotificationResponse"); + if (!center || ![center isKindOfClass:[notificationCenterClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!response || ![response isKindOfClass:[responseClass class]]) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + if (!handler) { + // Invalid parameter type from the original method. + // Do not swizzle, just execute the original method. + callOriginalMethodIfAvailable(); + return; + } + + // Try to access the response.notification property + SEL notificationSelector = NSSelectorFromString(@"notification"); + if (![response respondsToSelector:notificationSelector]) { + // Cannot access the .notification property. + callOriginalMethodIfAvailable(); + return; + } + id notificationClass = NSClassFromString(@"UNNotification"); + id notification = + FIRMessagingPropertyNameFromObject(response, @"notification", notificationClass); + + // With a notification object, use the common code to reach deep into notification + // (notification.request.content.userInfo) + id notificationUserInfo = FIRMessagingUserInfoFromNotification(notification); + if (!notificationUserInfo) { + // Could not access notification.request.content.userInfo. + callOriginalMethodIfAvailable(); + return; + } + + [[FIRMessaging messaging] appDidReceiveMessage:notificationUserInfo]; + // Execute the original implementation. + callOriginalMethodIfAvailable(); +} + +static id FIRMessagingUserInfoFromNotification(id notification) { + // Select the userInfo field from UNNotification.request.content.userInfo. + SEL requestSelector = NSSelectorFromString(@"request"); + if (![notification respondsToSelector:requestSelector]) { + // Cannot access the request property. + return nil; + } + Class requestClass = NSClassFromString(@"UNNotificationRequest"); + id notificationRequest = + FIRMessagingPropertyNameFromObject(notification, @"request", requestClass); + + SEL notificationContentSelector = NSSelectorFromString(@"content"); + if (!notificationRequest || + ![notificationRequest respondsToSelector:notificationContentSelector]) { + // Cannot access the content property. + return nil; + } + Class contentClass = NSClassFromString(@"UNNotificationContent"); + id notificationContent = + FIRMessagingPropertyNameFromObject(notificationRequest, @"content", contentClass); + + SEL notificationUserInfoSelector = NSSelectorFromString(@"userInfo"); + if (!notificationContent || + ![notificationContent respondsToSelector:notificationUserInfoSelector]) { + // Cannot access the userInfo property. + return nil; + } + id notificationUserInfo = + FIRMessagingPropertyNameFromObject(notificationContent, @"userInfo", [NSDictionary class]); + + if (!notificationUserInfo) { + // This is not the expected notification handler. + return nil; + } + + return notificationUserInfo; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRmqManager.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRmqManager.h new file mode 100644 index 00000000..34eaf4ce --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRmqManager.h @@ -0,0 +1,164 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class GtalkDataMessageStanza; +@class GPBMessage; + +@class FIRMessagingPersistentSyncMessage; + +/** + * Called on each raw message. + */ +typedef void (^FIRMessagingRmqMessageHandler)(NSDictionary<NSString *, GPBMessage *> *messages); + +/** + * Used to scan through the rmq and perform actions on messages as required. + */ +@protocol FIRMessagingRmqScanner <NSObject> + +/** + * Scan the RMQ for outgoing messages and process them as required. + */ +- (void)scanWithRmqMessageHandler:(FIRMessagingRmqMessageHandler)rmqMessageHandler; + +@end + +/** + * This manages the RMQ persistent store. + * + * The store is used to store all the S2D id's that were received by the client and were ACK'ed + * by us but the server hasn't confirmed the ACK. We don't delete these id's until the server + * ACK's us that they have received them. + * + * We also store the upstream messages(d2s) that were sent by the client. + * + * Also store the lastRMQId that was sent by us so that for a new connection being setup we don't + * duplicate RMQ Id's for the new messages. + */ +@interface FIRMessagingRmqManager : NSObject <FIRMessagingRmqScanner> + +// designated initializer +- (instancetype)initWithDatabaseName:(NSString *)databaseName; + +- (void)loadRmqId; + +/** + * Save an upstream message to RMQ. If the message send fails for some reason we would not + * lose the message since it would be saved in the RMQ. + * + * @param message The upstream message to be saved. + * @param handler The handler to invoke when the database operation completes with response. + * + */ +- (void)saveRmqMessage:(GPBMessage *)message withCompletionHandler:(void (^)(BOOL success))handler; + +/** + * Save Server to device message with the given RMQ-ID. + * + * @param rmqID The rmqID of the s2d message to save. + * + */ +- (void)saveS2dMessageWithRmqId:(NSString *)rmqID; + +/** + * A list of all unacked Server to device RMQ IDs. + * + * @return A list of unacked Server to Device RMQ ID's. All values are Strings. + */ +- (NSArray *)unackedS2dRmqIds; + +/** + * Removes the messages with the given rmqIDs from RMQ store. + * + * @param rmqIds The lsit of rmqID's to remove from the store. + * + */ +- (void)removeRmqMessagesWithRmqIds:(NSArray *)rmqIds; + +/** + * Removes a list of downstream messages from the RMQ. + * + * @param s2dIds The list of messages ACK'ed by the server that we should remove + * from the RMQ store. + */ +- (void)removeS2dIds:(NSArray *)s2dIds; + +#pragma mark - Sync Messages + +/** + * Get persisted sync message with rmqID. + * + * @param rmqID The rmqID of the persisted sync message. + * + * @return A valid persistent sync message with the given rmqID if found in the RMQ else nil. + */ +- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID; + +/** + * Delete sync message with rmqID. + * + * @param rmqID The rmqID of the persisted sync message. + * + */ +- (void)deleteSyncMessageWithRmqID:(NSString *)rmqID; + +/** + * Delete the expired sync messages from persisten store. Also deletes messages that have been + * delivered both via APNS and MCS. + * + */ +- (void)deleteExpiredOrFinishedSyncMessages; + +/** + * Save sync message received by the device. + * + * @param rmqID The rmqID of the message received. + * @param expirationTime The expiration time of the sync message received. + * @param apnsReceived YES if the message was received via APNS else NO. + * @param mcsReceived YES if the message was received via MCS else NO. + * + */ +- (void)saveSyncMessageWithRmqID:(NSString *)rmqID + expirationTime:(int64_t)expirationTime + apnsReceived:(BOOL)apnsReceived + mcsReceived:(BOOL)mcsReceived; + +/** + * Update sync message received via APNS. + * + * @param rmqID The rmqID of the received message. + * + */ +- (void)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID; + +/** + * Update sync message received via MCS. + * + * @param rmqID The rmqID of the received message. + * + */ +- (void)updateSyncMessageViaMCSWithRmqID:(NSString *)rmqID; + +/** + * Returns path for database with specified name. + * @param databaseName The database name without extension: "<databaseName>.sqlite". + * @returns Path to the database with the specified name. + */ ++ (NSString *)pathForDatabaseWithName:(NSString *)databaseName; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRmqManager.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRmqManager.m new file mode 100644 index 00000000..0390a5b8 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingRmqManager.m @@ -0,0 +1,825 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" + +#import <sqlite3.h> + +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" +#import "FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h" + +#ifndef _FIRMessagingRmqLogAndExit +#define _FIRMessagingRmqLogAndExit(stmt, return_value) \ + do { \ + [self logErrorAndFinalizeStatement:stmt]; \ + return return_value; \ + } while (0) +#endif + +#ifndef FIRMessagingRmqLogAndReturn +#define FIRMessagingRmqLogAndReturn(stmt) \ + do { \ + [self logErrorAndFinalizeStatement:stmt]; \ + return; \ + } while (0) +#endif + +#ifndef FIRMessaging_MUST_NOT_BE_MAIN_THREAD +#define FIRMessaging_MUST_NOT_BE_MAIN_THREAD() \ + do { \ + NSAssert(![NSThread isMainThread], @"Must not be executing on the main thread."); \ + } while (0); +#endif + +// table names +NSString *const kTableOutgoingRmqMessages = @"outgoingRmqMessages"; +NSString *const kTableLastRmqId = @"lastrmqid"; +NSString *const kOldTableS2DRmqIds = @"s2dRmqIds"; +NSString *const kTableS2DRmqIds = @"s2dRmqIds_1"; + +// Used to prevent de-duping of sync messages received both via APNS and MCS. +NSString *const kTableSyncMessages = @"incomingSyncMessages"; + +static NSString *const kTablePrefix = @""; + +// create tables +static NSString *const kCreateTableOutgoingRmqMessages = @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id INTEGER, " + @"type INTEGER, " + @"ts INTEGER, " + @"data BLOB)"; + +static NSString *const kCreateTableLastRmqId = @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id INTEGER)"; + +static NSString *const kCreateTableS2DRmqIds = @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id TEXT)"; + +static NSString *const kCreateTableSyncMessages = @"create TABLE IF NOT EXISTS %@%@ " + @"(_id INTEGER PRIMARY KEY, " + @"rmq_id TEXT, " + @"expiration_ts INTEGER, " + @"apns_recv INTEGER, " + @"mcs_recv INTEGER)"; + +static NSString *const kDropTableCommand = @"drop TABLE if exists %@%@"; + +// table infos +static NSString *const kRmqIdColumn = @"rmq_id"; +static NSString *const kDataColumn = @"data"; +static NSString *const kProtobufTagColumn = @"type"; +static NSString *const kIdColumn = @"_id"; + +static NSString *const kOutgoingRmqMessagesColumns = @"rmq_id, type, data"; + +// Sync message columns +static NSString *const kSyncMessagesColumns = @"rmq_id, expiration_ts, apns_recv, mcs_recv"; +// Message time expiration in seconds since 1970 +static NSString *const kSyncMessageExpirationTimestampColumn = @"expiration_ts"; +static NSString *const kSyncMessageAPNSReceivedColumn = @"apns_recv"; +static NSString *const kSyncMessageMCSReceivedColumn = @"mcs_recv"; + +// Utility to create an NSString from a sqlite3 result code +NSString *_Nonnull FIRMessagingStringFromSQLiteResult(int result) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + const char *errorStr = sqlite3_errstr(result); +#pragma clang diagnostic pop + NSString *errorString = [NSString stringWithFormat:@"%d - %s", result, errorStr]; + return errorString; +} + +@interface FIRMessagingRmqManager () { + sqlite3 *_database; + /// Serial queue for database read/write operations. + dispatch_queue_t _databaseOperationQueue; +} + +@property(nonatomic, readwrite, strong) NSString *databaseName; +// map the category of an outgoing message with the number of messages for that category +// should always have two keys -- the app, gcm +@property(nonatomic, readwrite, strong) NSMutableDictionary *outstandingMessages; + +// Outgoing RMQ persistent id +@property(nonatomic, readwrite, assign) int64_t rmqId; +@end + +@implementation FIRMessagingRmqManager + +- (instancetype)initWithDatabaseName:(NSString *)databaseName { + self = [super init]; + if (self) { + _databaseOperationQueue = + dispatch_queue_create("com.google.firebase.messaging.database.rmq", DISPATCH_QUEUE_SERIAL); + _databaseName = [databaseName copy]; + [self openDatabase]; + _outstandingMessages = [NSMutableDictionary dictionaryWithCapacity:2]; + _rmqId = -1; + } + return self; +} + +- (void)dealloc { + sqlite3_close(_database); +} + +#pragma mark - RMQ ID + +- (void)loadRmqId { + if (self.rmqId >= 0) { + return; // already done + } + + [self loadInitialOutgoingPersistentId]; + if (self.outstandingMessages.count) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmqManager000, @"Outstanding categories %ld", + _FIRMessaging_UL(self.outstandingMessages.count)); + } +} + +/** + * Initialize the 'initial RMQ': + * - max ID of any message in the queue + * - if the queue is empty, stored value in separate DB. + * + * Stream acks will remove from RMQ, when we remove the highest message we keep track + * of its ID. + */ +- (void)loadInitialOutgoingPersistentId { + // we shouldn't always trust the lastRmqId stored in the LastRmqId table, because + // we only save to the LastRmqId table once in a while (after getting the lastRmqId sent + // by the server after reconnect, and after getting a rmq ack from the server). The + // rmq message with the highest rmq id tells the real story, so check against that first. + + __block int64_t rmqId; + dispatch_sync(_databaseOperationQueue, ^{ + rmqId = [self queryHighestRmqId]; + }); + if (rmqId == 0) { + dispatch_sync(_databaseOperationQueue, ^{ + rmqId = [self queryLastRmqId]; + }); + } + self.rmqId = rmqId + 1; +} + +#pragma mark - Save + +/** + * Save a message to RMQ2. Will populate the rmq2 persistent ID. + */ +- (void)saveRmqMessage:(GPBMessage *)message withCompletionHandler:(void (^)(BOOL success))handler { + // send using rmq2manager + // the wire format of rmq2 id is a string. However, we keep it as a long internally + // in the database. So only convert the id to string when preparing for sending over + // the wire. + NSString *rmq2Id = FIRMessagingGetRmq2Id(message); + if (![rmq2Id length]) { + int64_t rmqId = [self nextRmqId]; + rmq2Id = [NSString stringWithFormat:@"%lld", rmqId]; + FIRMessagingSetRmq2Id(message, rmq2Id); + } + FIRMessagingProtoTag tag = FIRMessagingGetTagForProto(message); + NSData *data = [message data]; + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [self saveMessageWithRmqId:[rmq2Id integerValue] tag:tag data:data]; + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(success); + }); + } + }); +} + +/** + * This is called when we delete the largest outgoing message from queue. + */ +- (void)saveLastOutgoingRmqId:(int64_t)rmqID { + dispatch_async(_databaseOperationQueue, ^{ + NSString *queryFormat = @"INSERT OR REPLACE INTO %@ (%@, %@) VALUES (?, ?)"; + NSString *query = [NSString stringWithFormat:queryFormat, + kTableLastRmqId, // table + kIdColumn, kRmqIdColumn]; // columns + sqlite3_stmt *statement; + if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &statement, NULL) != + SQLITE_OK) { + FIRMessagingRmqLogAndReturn(statement); + } + if (sqlite3_bind_int(statement, 1, 1) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(statement); + } + if (sqlite3_bind_int64(statement, 2, rmqID) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(statement); + } + if (sqlite3_step(statement) != SQLITE_DONE) { + FIRMessagingRmqLogAndReturn(statement); + } + sqlite3_finalize(statement); + }); +} + +- (void)saveS2dMessageWithRmqId:(NSString *)rmqId { + dispatch_async(_databaseOperationQueue, ^{ + NSString *insertFormat = @"INSERT INTO %@ (%@) VALUES (?)"; + NSString *insertSQL = [NSString stringWithFormat:insertFormat, kTableS2DRmqIds, kRmqIdColumn]; + sqlite3_stmt *insert_statement; + if (sqlite3_prepare_v2(self->_database, [insertSQL UTF8String], -1, &insert_statement, NULL) != + SQLITE_OK) { + FIRMessagingRmqLogAndReturn(insert_statement); + } + if (sqlite3_bind_text(insert_statement, 1, [rmqId UTF8String], (int)[rmqId length], + SQLITE_STATIC) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(insert_statement); + } + if (sqlite3_step(insert_statement) != SQLITE_DONE) { + FIRMessagingRmqLogAndReturn(insert_statement); + } + sqlite3_finalize(insert_statement); + }); +} + +#pragma mark - Query + +- (int64_t)queryHighestRmqId { + NSString *queryFormat = @"SELECT %@ FROM %@ ORDER BY %@ DESC LIMIT %d"; + NSString *query = [NSString stringWithFormat:queryFormat, + kRmqIdColumn, // column + kTableOutgoingRmqMessages, // table + kRmqIdColumn, // order by column + 1]; // limit + + sqlite3_stmt *statement; + int64_t highestRmqId = 0; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, highestRmqId); + } + if (sqlite3_step(statement) == SQLITE_ROW) { + highestRmqId = sqlite3_column_int64(statement, 0); + } + sqlite3_finalize(statement); + return highestRmqId; +} + +- (int64_t)queryLastRmqId { + NSString *queryFormat = @"SELECT %@ FROM %@ ORDER BY %@ DESC LIMIT %d"; + NSString *query = [NSString stringWithFormat:queryFormat, + kRmqIdColumn, // column + kTableLastRmqId, // table + kRmqIdColumn, // order by column + 1]; // limit + + sqlite3_stmt *statement; + int64_t lastRmqId = 0; + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(statement, lastRmqId); + } + if (sqlite3_step(statement) == SQLITE_ROW) { + lastRmqId = sqlite3_column_int64(statement, 0); + } + sqlite3_finalize(statement); + return lastRmqId; +} + +- (NSArray *)unackedS2dRmqIds { + __block NSMutableArray *rmqIDArray = [NSMutableArray array]; + dispatch_sync(_databaseOperationQueue, ^{ + NSString *queryFormat = @"SELECT %@ FROM %@ ORDER BY %@ ASC"; + NSString *query = + [NSString stringWithFormat:queryFormat, kRmqIdColumn, kTableS2DRmqIds, kRmqIdColumn]; + sqlite3_stmt *statement; + if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &statement, NULL) != + SQLITE_OK) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore005, + @"Could not find s2d ids"); + FIRMessagingRmqLogAndReturn(statement); + } + while (sqlite3_step(statement) == SQLITE_ROW) { + const char *rmqID = (char *)sqlite3_column_text(statement, 0); + [rmqIDArray addObject:[NSString stringWithUTF8String:rmqID]]; + } + sqlite3_finalize(statement); + }); + return rmqIDArray; +} + +#pragma mark - FIRMessagingRMQScanner protocol + +#pragma mark - Remove +- (void)removeRmqMessagesWithRmqIds:(NSArray *)rmqIds { + if (![rmqIds count]) { + return; + } + int64_t maxRmqId = -1; + for (NSString *rmqId in rmqIds) { + int64_t rmqIdValue = [rmqId longLongValue]; + if (rmqIdValue > maxRmqId) { + maxRmqId = rmqIdValue; + } + } + maxRmqId++; + if (maxRmqId >= self.rmqId) { + [self saveLastOutgoingRmqId:maxRmqId]; + } + [self deleteMessagesFromTable:kTableOutgoingRmqMessages withRmqIds:rmqIds]; +} + +- (void)removeS2dIds:(NSArray *)s2dIds { + [self deleteMessagesFromTable:kTableS2DRmqIds withRmqIds:s2dIds]; +} + +#pragma mark - Sync Messages + +- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID { + __block FIRMessagingPersistentSyncMessage *persistentMessage; + dispatch_sync(_databaseOperationQueue, ^{ + NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ = '%@'"; + NSString *query = + [NSString stringWithFormat:queryFormat, + kSyncMessagesColumns, // SELECT (rmq_id, expiration_ts, + // apns_recv, mcs_recv) + kTableSyncMessages, // FROM sync_rmq + kRmqIdColumn, // WHERE rmq_id + rmqID]; + + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + [self logError]; + sqlite3_finalize(stmt); + return; + } + + const int rmqIDColumn = 0; + const int expirationTimestampColumn = 1; + const int apnsReceivedColumn = 2; + const int mcsReceivedColumn = 3; + + int count = 0; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + NSString *rmqID = + [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, rmqIDColumn)]; + int64_t expirationTimestamp = sqlite3_column_int64(stmt, expirationTimestampColumn); + BOOL apnsReceived = sqlite3_column_int(stmt, apnsReceivedColumn); + BOOL mcsReceived = sqlite3_column_int(stmt, mcsReceivedColumn); + + // create a new persistent message + persistentMessage = + [[FIRMessagingPersistentSyncMessage alloc] initWithRMQID:rmqID + expirationTime:expirationTimestamp]; + persistentMessage.apnsReceived = apnsReceived; + persistentMessage.mcsReceived = mcsReceived; + + count++; + } + sqlite3_finalize(stmt); + }); + + return persistentMessage; +} + +- (void)deleteSyncMessageWithRmqID:(NSString *)rmqID { + [self deleteMessagesFromTable:kTableSyncMessages withRmqIds:@[ rmqID ]]; +} + +- (void)deleteExpiredOrFinishedSyncMessages { + dispatch_async(_databaseOperationQueue, ^{ + int64_t now = FIRMessagingCurrentTimestampInSeconds(); + NSString *deleteSQL = @"DELETE FROM %@ " + @"WHERE %@ < %lld OR " // expirationTime < now + @"(%@ = 1 AND %@ = 1)"; // apns_received = 1 AND mcs_received = 1 + NSString *query = [NSString + stringWithFormat:deleteSQL, kTableSyncMessages, kSyncMessageExpirationTimestampColumn, now, + kSyncMessageAPNSReceivedColumn, kSyncMessageMCSReceivedColumn]; + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(stmt); + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + FIRMessagingRmqLogAndReturn(stmt); + } + + sqlite3_finalize(stmt); + int deleteCount = sqlite3_changes(self->_database); + if (deleteCount > 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSyncMessageManager001, + @"Successfully deleted %d sync messages from store", deleteCount); + } + }); +} + +- (void)saveSyncMessageWithRmqID:(NSString *)rmqID + expirationTime:(int64_t)expirationTime + apnsReceived:(BOOL)apnsReceived + mcsReceived:(BOOL)mcsReceived { + dispatch_async(_databaseOperationQueue, ^{ + NSString *insertFormat = @"INSERT INTO %@ (%@, %@, %@, %@) VALUES (?, ?, ?, ?)"; + NSString *insertSQL = + [NSString stringWithFormat:insertFormat, + kTableSyncMessages, // Table name + kRmqIdColumn, // rmq_id + kSyncMessageExpirationTimestampColumn, // expiration_ts + kSyncMessageAPNSReceivedColumn, // apns_recv + kSyncMessageMCSReceivedColumn /* mcs_recv */]; + + sqlite3_stmt *stmt; + + if (sqlite3_prepare_v2(self->_database, [insertSQL UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(stmt); + } + + if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], NULL) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(stmt); + } + + if (sqlite3_bind_int64(stmt, 2, expirationTime) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(stmt); + } + + if (sqlite3_bind_int(stmt, 3, apnsReceived ? 1 : 0) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(stmt); + } + + if (sqlite3_bind_int(stmt, 4, mcsReceived ? 1 : 0) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(stmt); + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + FIRMessagingRmqLogAndReturn(stmt); + } + sqlite3_finalize(stmt); + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager004, + @"Added sync message to cache: %@", rmqID); + }); +} + +- (void)updateSyncMessageViaAPNSWithRmqID:(NSString *)rmqID { + dispatch_async(_databaseOperationQueue, ^{ + if (![self updateSyncMessageWithRmqID:rmqID column:kSyncMessageAPNSReceivedColumn value:YES]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager005, + @"Failed to update APNS state for sync message %@", rmqID); + } + }); +} + +- (void)updateSyncMessageViaMCSWithRmqID:(NSString *)rmqID { + dispatch_async(_databaseOperationQueue, ^{ + if (![self updateSyncMessageWithRmqID:rmqID column:kSyncMessageMCSReceivedColumn value:YES]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager006, + @"Failed to update MCS state for sync message %@", rmqID); + } + }); +} + +- (BOOL)updateSyncMessageWithRmqID:(NSString *)rmqID column:(NSString *)column value:(BOOL)value { + FIRMessaging_MUST_NOT_BE_MAIN_THREAD(); + NSString *queryFormat = @"UPDATE %@ " // Table name + @"SET %@ = %d " // column=value + @"WHERE %@ = ?"; // condition + NSString *query = [NSString + stringWithFormat:queryFormat, kTableSyncMessages, column, value ? 1 : 0, kRmqIdColumn]; + sqlite3_stmt *stmt; + + if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(stmt, NO); + } + + sqlite3_finalize(stmt); + return YES; +} + +#pragma mark - Database + +- (NSString *)pathForDatabase { + return [[self class] pathForDatabaseWithName:_databaseName]; +} + ++ (NSString *)pathForDatabaseWithName:(NSString *)databaseName { + NSString *dbNameWithExtension = [NSString stringWithFormat:@"%@.sqlite", databaseName]; + NSArray *paths = + NSSearchPathForDirectoriesInDomains(FIRMessagingSupportedDirectory(), NSUserDomainMask, YES); + NSArray *components = @[ paths.lastObject, kFIRMessagingSubDirectoryName, dbNameWithExtension ]; + return [NSString pathWithComponents:components]; +} + +- (void)createTableWithName:(NSString *)tableName command:(NSString *)command { + FIRMessaging_MUST_NOT_BE_MAIN_THREAD(); + char *error; + NSString *createDatabase = [NSString stringWithFormat:command, kTablePrefix, tableName]; + if (sqlite3_exec(self->_database, [createDatabase UTF8String], NULL, NULL, &error) != SQLITE_OK) { + // remove db before failing + [self removeDatabase]; + NSString *errorMessage = [NSString + stringWithFormat:@"Couldn't create table: %@ %@", kCreateTableOutgoingRmqMessages, + [NSString stringWithCString:error encoding:NSUTF8StringEncoding]]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingTable, @"%@", + errorMessage); + NSAssert(NO, errorMessage); + } +} + +- (void)dropTableWithName:(NSString *)tableName { + FIRMessaging_MUST_NOT_BE_MAIN_THREAD(); + char *error; + NSString *dropTableSQL = [NSString stringWithFormat:kDropTableCommand, kTablePrefix, tableName]; + if (sqlite3_exec(self->_database, [dropTableSQL UTF8String], NULL, NULL, &error) != SQLITE_OK) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore002, + @"Failed to remove table %@", tableName); + } +} + +- (void)removeDatabase { + // Ensure database is removed in a sync queue as this sometimes makes test have race conditions. + dispatch_async(_databaseOperationQueue, ^{ + NSString *path = [self pathForDatabase]; + [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; + }); +} + +- (void)openDatabase { + dispatch_async(_databaseOperationQueue, ^{ + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *path = [self pathForDatabase]; + + BOOL didOpenDatabase = YES; + if (![fileManager fileExistsAtPath:path]) { + // We've to separate between different versions here because of backwards compatbility issues. + int result = sqlite3_open_v2( + [path UTF8String], &self -> _database, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL); + if (result != SQLITE_OK) { + NSString *errorString = FIRMessagingStringFromSQLiteResult(result); + NSString *errorMessage = [NSString + stringWithFormat:@"Could not open existing RMQ database at path %@, error: %@", path, + errorString]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase, + @"%@", errorMessage); + NSAssert(NO, errorMessage); + return; + } + [self createTableWithName:kTableOutgoingRmqMessages command:kCreateTableOutgoingRmqMessages]; + + [self createTableWithName:kTableLastRmqId command:kCreateTableLastRmqId]; + [self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds]; + } else { + // Calling sqlite3_open should create the database, since the file doesn't exist. + int result = sqlite3_open_v2( + [path UTF8String], &self -> _database, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL); + if (result != SQLITE_OK) { + NSString *errorString = FIRMessagingStringFromSQLiteResult(result); + NSString *errorMessage = + [NSString stringWithFormat:@"Could not create RMQ database at path %@, error: %@", path, + errorString]; + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase, + @"%@", errorMessage); + NSAssert(NO, errorMessage); + didOpenDatabase = NO; + } else { + [self updateDBWithStringRmqID]; + } + } + + if (didOpenDatabase) { + [self createTableWithName:kTableSyncMessages command:kCreateTableSyncMessages]; + } + }); +} + +- (void)updateDBWithStringRmqID { + dispatch_async(_databaseOperationQueue, ^{ + [self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds]; + [self dropTableWithName:kOldTableS2DRmqIds]; + }); +} + +#pragma mark - Scan + +/** + * We don't have a 'getMessages' method - it would require loading in memory + * the entire content body of all messages. + * + * Instead we iterate and call 'resend' for each message. + * + * This is called: + * - on connect MCS, to resend any outstanding messages + * - init + */ +- (void)scanWithRmqMessageHandler:(FIRMessagingRmqMessageHandler)rmqMessageHandler { + dispatch_async(_databaseOperationQueue, ^{ + NSMutableDictionary *messages = [NSMutableDictionary dictionary]; + static NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ != 0 ORDER BY %@ ASC"; + NSString *query = + [NSString stringWithFormat:queryFormat, + kOutgoingRmqMessagesColumns, // select (rmq_id, type, data) + kTableOutgoingRmqMessages, // from table + kRmqIdColumn, // where + kRmqIdColumn]; // order by + sqlite3_stmt *statement; + if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &statement, NULL) != + SQLITE_OK) { + [self logError]; + sqlite3_finalize(statement); + if (rmqMessageHandler) { + dispatch_async(dispatch_get_main_queue(), ^{ + rmqMessageHandler(messages); + }); + } + } + // can query sqlite3 for this but this is fine + const int rmqIdColumnNumber = 0; + const int typeColumnNumber = 1; + const int dataColumnNumber = 2; + while (sqlite3_step(statement) == SQLITE_ROW) { + int64_t rmqId = sqlite3_column_int64(statement, rmqIdColumnNumber); + int8_t type = sqlite3_column_int(statement, typeColumnNumber); + const void *bytes = sqlite3_column_blob(statement, dataColumnNumber); + int length = sqlite3_column_bytes(statement, dataColumnNumber); + + NSData *data = [NSData dataWithBytes:bytes length:length]; + GPBMessage *proto = + [FIRMessagingGetClassForTag((FIRMessagingProtoTag)type) parseFromData:data error:NULL]; + [messages addEntriesFromDictionary:@{@(rmqId) : proto}]; + } + sqlite3_finalize(statement); + if (rmqMessageHandler) { + dispatch_async(dispatch_get_main_queue(), ^{ + rmqMessageHandler(messages); + }); + } + }); +} + +#pragma mark - Private + +- (BOOL)saveMessageWithRmqId:(int64_t)rmqId tag:(int8_t)tag data:(NSData *)data { + FIRMessaging_MUST_NOT_BE_MAIN_THREAD(); + NSString *insertFormat = @"INSERT INTO %@ (%@, %@, %@) VALUES (?, ?, ?)"; + NSString *insertSQL = + [NSString stringWithFormat:insertFormat, + kTableOutgoingRmqMessages, // table + kRmqIdColumn, kProtobufTagColumn, kDataColumn /* columns */]; + sqlite3_stmt *insert_statement; + if (sqlite3_prepare_v2(self->_database, [insertSQL UTF8String], -1, &insert_statement, NULL) != + SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_int64(insert_statement, 1, rmqId) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_int(insert_statement, 2, tag) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_bind_blob(insert_statement, 3, [data bytes], (int)[data length], NULL) != SQLITE_OK) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + if (sqlite3_step(insert_statement) != SQLITE_DONE) { + _FIRMessagingRmqLogAndExit(insert_statement, NO); + } + + sqlite3_finalize(insert_statement); + + return YES; +} + +- (void)deleteMessagesFromTable:(NSString *)tableName withRmqIds:(NSArray *)rmqIds { + dispatch_async(_databaseOperationQueue, ^{ + BOOL isRmqIDString = NO; + // RmqID is a string only for outgoing messages + if ([tableName isEqualToString:kTableS2DRmqIds] || + [tableName isEqualToString:kTableSyncMessages]) { + isRmqIDString = YES; + } + + NSMutableString *delete = + [NSMutableString stringWithFormat:@"DELETE FROM %@ WHERE ", tableName]; + + NSString *toDeleteArgument = [NSString stringWithFormat:@"%@ = ? OR ", kRmqIdColumn]; + + int toDelete = (int)[rmqIds count]; + if (toDelete == 0) { + return; + } + int maxBatchSize = 100; + int start = 0; + int deleteCount = 0; + while (start < toDelete) { + // construct the WHERE argument + int end = MIN(start + maxBatchSize, toDelete); + NSMutableString *whereArgument = [NSMutableString string]; + for (int i = start; i < end; i++) { + [whereArgument appendString:toDeleteArgument]; + } + // remove the last * OR * from argument + NSRange range = NSMakeRange([whereArgument length] - 4, 4); + [whereArgument deleteCharactersInRange:range]; + NSString *deleteQuery = [NSString stringWithFormat:@"%@ %@", delete, whereArgument]; + + // sqlite update + sqlite3_stmt *delete_statement; + if (sqlite3_prepare_v2(self->_database, [deleteQuery UTF8String], -1, &delete_statement, + NULL) != SQLITE_OK) { + FIRMessagingRmqLogAndReturn(delete_statement); + } + + // bind values + int rmqIndex = 0; + int placeholderIndex = 1; // placeholders in sqlite3 start with 1 + for (NSString *rmqId in rmqIds) { // objectAtIndex: is O(n) -- would make it slow + if (rmqIndex < start) { + rmqIndex++; + continue; + } else if (rmqIndex >= end) { + break; + } else { + if (isRmqIDString) { + if (sqlite3_bind_text(delete_statement, placeholderIndex, [rmqId UTF8String], + (int)[rmqId length], SQLITE_STATIC) != SQLITE_OK) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore003, + @"Failed to bind rmqID %@", rmqId); + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager007, + @"Failed to delete sync message %@", rmqId); + continue; + } + } else { + int64_t rmqIdValue = [rmqId longLongValue]; + sqlite3_bind_int64(delete_statement, placeholderIndex, rmqIdValue); + } + placeholderIndex++; + } + rmqIndex++; + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeSyncMessageManager008, + @"Successfully deleted sync message from cache %@", rmqId); + } + if (sqlite3_step(delete_statement) != SQLITE_DONE) { + FIRMessagingRmqLogAndReturn(delete_statement); + } + sqlite3_finalize(delete_statement); + deleteCount += sqlite3_changes(self->_database); + start = end; + } + + // if we are here all of our sqlite queries should have succeeded + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeRmq2PersistentStore004, + @"Trying to delete %d s2D ID's, successfully deleted %d", toDelete, + deleteCount); + }); +} + +- (int64_t)nextRmqId { + return ++self.rmqId; +} + +- (NSString *)lastErrorMessage { + return [NSString stringWithFormat:@"%s", sqlite3_errmsg(_database)]; +} + +- (int)lastErrorCode { + return sqlite3_errcode(_database); +} + +- (void)logError { + FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStore006, + @"Error: code (%d) message: %@", [self lastErrorCode], + [self lastErrorMessage]); +} + +- (void)logErrorAndFinalizeStatement:(sqlite3_stmt *)stmt { + [self logError]; + sqlite3_finalize(stmt); +} + +- (dispatch_queue_t)databaseOperationQueue { + return _databaseOperationQueue; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSecureSocket.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSecureSocket.h new file mode 100644 index 00000000..8d47523d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSecureSocket.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +typedef NS_ENUM(NSUInteger, FIRMessagingSecureSocketState) { + kFIRMessagingSecureSocketNotOpen = 0, + kFIRMessagingSecureSocketOpening, + kFIRMessagingSecureSocketOpen, + kFIRMessagingSecureSocketClosing, + kFIRMessagingSecureSocketClosed, + kFIRMessagingSecureSocketError +}; + +@class FIRMessagingSecureSocket; + +@protocol FIRMessagingSecureSocketDelegate <NSObject> + +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didReceiveData:(NSData *)data + withTag:(int8_t)tag; +- (void)secureSocket:(FIRMessagingSecureSocket *)socket + didSendProtoWithTag:(int8_t)tag + rmqId:(NSString *)rmqId; +- (void)secureSocketDidConnect:(FIRMessagingSecureSocket *)socket; +- (void)didDisconnectWithSecureSocket:(FIRMessagingSecureSocket *)socket; + +@end + +/** + * This manages the input/output streams connected to the MCS server. Used to receive data from + * the server and send to it over the wire. + */ +@interface FIRMessagingSecureSocket : NSObject + +@property(nonatomic, readwrite, weak) id<FIRMessagingSecureSocketDelegate> delegate; +@property(nonatomic, readonly, assign) FIRMessagingSecureSocketState state; + +- (void)connectToHost:(NSString *)host port:(NSUInteger)port onRunLoop:(NSRunLoop *)runLoop; +- (void)disconnect; +- (void)sendData:(NSData *)data withTag:(int8_t)tag rmqId:(NSString *)rmqId; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSecureSocket.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSecureSocket.m new file mode 100644 index 00000000..8f806aed --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSecureSocket.m @@ -0,0 +1,404 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingSecureSocket.h" + +#import <Protobuf/GPBCodedOutputStream.h> +#import <Protobuf/GPBMessage.h> +#import <Protobuf/GPBUtilities.h> + +#import "FirebaseMessaging/Sources/FIRMessagingCodedInputStream.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPacketQueue.h" + +static const NSUInteger kMaxBufferLength = 1024 * 1024; // 1M +static const NSUInteger kBufferLengthIncrement = 16 * 1024; // 16k +static const uint8_t kVersion = 40; +static const uint8_t kInvalidTag = -1; + +typedef NS_ENUM(NSUInteger, FIRMessagingSecureSocketReadResult) { + kFIRMessagingSecureSocketReadResultNone, + kFIRMessagingSecureSocketReadResultIncomplete, + kFIRMessagingSecureSocketReadResultCorrupt, + kFIRMessagingSecureSocketReadResultSuccess +}; + +static int32_t LogicalRightShift32(int32_t value, int32_t spaces) { + return (int32_t)((uint32_t)(value) >> spaces); +} + +static NSUInteger SerializedSize(int32_t value) { + NSUInteger bytes = 0; + while (YES) { + if ((value & ~0x7F) == 0) { + bytes += sizeof(uint8_t); + return bytes; + } else { + bytes += sizeof(uint8_t); + value = LogicalRightShift32(value, 7); + } + } +} + +@interface FIRMessagingSecureSocket () <NSStreamDelegate> + +@property(nonatomic, readwrite, assign) FIRMessagingSecureSocketState state; +@property(nonatomic, readwrite, strong) NSInputStream *inStream; +@property(nonatomic, readwrite, strong) NSOutputStream *outStream; + +@property(nonatomic, readwrite, strong) NSMutableData *inputBuffer; +@property(nonatomic, readwrite, assign) NSUInteger inputBufferLength; +@property(nonatomic, readwrite, strong) NSMutableData *outputBuffer; +@property(nonatomic, readwrite, assign) NSUInteger outputBufferLength; + +@property(nonatomic, readwrite, strong) FIRMessagingPacketQueue *packetQueue; +@property(nonatomic, readwrite, assign) BOOL isVersionSent; +@property(nonatomic, readwrite, assign) BOOL isVersionReceived; +@property(nonatomic, readwrite, assign) BOOL isInStreamOpen; +@property(nonatomic, readwrite, assign) BOOL isOutStreamOpen; + +@property(nonatomic, readwrite, strong) NSRunLoop *runLoop; +@property(nonatomic, readwrite, strong) NSString *currentRmqIdBeingSent; +@property(nonatomic, readwrite, assign) int8_t currentProtoTypeBeingSent; + +@end + +@implementation FIRMessagingSecureSocket + +- (instancetype)init { + self = [super init]; + if (self) { + _state = kFIRMessagingSecureSocketNotOpen; + _inputBuffer = [NSMutableData dataWithLength:kBufferLengthIncrement]; + _packetQueue = [[FIRMessagingPacketQueue alloc] init]; + _currentProtoTypeBeingSent = kInvalidTag; + } + return self; +} + +- (void)dealloc { + [self disconnect]; +} + +- (void)connectToHost:(NSString *)host port:(NSUInteger)port onRunLoop:(NSRunLoop *)runLoop { + if (!host || self.state != kFIRMessagingSecureSocketNotOpen) { + return; + } + + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket000, + @"Opening secure socket to FIRMessaging service"); + self.state = kFIRMessagingSecureSocketOpening; + self.runLoop = runLoop; + CFReadStreamRef inputStreamRef; + CFWriteStreamRef outputStreamRef; + CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, (int)port, &inputStreamRef, + &outputStreamRef); + self.inStream = CFBridgingRelease(inputStreamRef); + self.outStream = CFBridgingRelease(outputStreamRef); + if (!self.inStream || !self.outStream) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket001, + @"Failed to initialize socket."); + return; + } + + self.isInStreamOpen = NO; + self.isOutStreamOpen = NO; + + BOOL isVOIPSocket = NO; + + [self openStream:self.outStream isVOIPStream:isVOIPSocket]; + [self openStream:self.inStream isVOIPStream:isVOIPSocket]; +} + +- (void)disconnect { + if (self.state == kFIRMessagingSecureSocketClosing) { + return; + } + if (!self.inStream && !self.outStream) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket002, + @"The socket is not open or already closed."); + return; + } + + self.state = kFIRMessagingSecureSocketClosing; + if (self.inStream) { + [self closeStream:self.inStream]; + self.inStream = nil; + } + if (self.outStream) { + [self closeStream:self.outStream]; + self.outStream = nil; + } + self.state = kFIRMessagingSecureSocketClosed; + [self.delegate didDisconnectWithSecureSocket:self]; +} + +- (void)sendData:(NSData *)data withTag:(int8_t)tag rmqId:(NSString *)rmqId { + [self.packetQueue push:[FIRMessagingPacket packetWithTag:tag rmqId:rmqId data:data]]; + if ([self.outStream hasSpaceAvailable]) { + [self performWrite]; + } +} + +#pragma mark - NSStreamDelegate + +- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode { + switch (eventCode) { + case NSStreamEventHasBytesAvailable: + if (self.state != kFIRMessagingSecureSocketOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket003, + @"Try to read from socket that is not opened"); + return; + } + if (![self performRead]) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket004, + @"Error occurred when reading incoming stream"); + [self disconnect]; + } + break; + case NSStreamEventEndEncountered: + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeSecureSocket005, @"%@ end encountered", + stream == self.inStream + ? @"Input stream" + : (stream == self.outStream ? @"Output stream" : @"Unknown stream")); + [self disconnect]; + break; + case NSStreamEventOpenCompleted: + if (stream == self.inStream) { + self.isInStreamOpen = YES; + } else if (stream == self.outStream) { + self.isOutStreamOpen = YES; + } + if (self.isInStreamOpen && self.isOutStreamOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket006, + @"Secure socket to FIRMessaging service opened"); + self.state = kFIRMessagingSecureSocketOpen; + [self.delegate secureSocketDidConnect:self]; + } + break; + case NSStreamEventErrorOccurred: { + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeSecureSocket007, @"%@ error occurred", + stream == self.inStream + ? @"Input stream" + : (stream == self.outStream ? @"Output stream" : @"Unknown stream")); + [self disconnect]; + break; + } + case NSStreamEventHasSpaceAvailable: + if (self.state != kFIRMessagingSecureSocketOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket008, + @"Try to write to socket that is not opened"); + return; + } + [self performWrite]; + break; + default: + break; + } +} + +#pragma mark - Private + +- (void)openStream:(NSStream *)stream isVOIPStream:(BOOL)isVOIPStream { + if (stream) { + if ([stream streamStatus] != NSStreamStatusNotOpen) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket009, + @"stream should not be open."); + return; + } + [stream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL + forKey:NSStreamSocketSecurityLevelKey]; + if (isVOIPStream) { + [stream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType]; + } + stream.delegate = self; + [stream scheduleInRunLoop:self.runLoop forMode:NSDefaultRunLoopMode]; + [stream open]; + } +} + +- (void)closeStream:(NSStream *)stream { + if (stream) { + [stream close]; + [stream removeFromRunLoop:self.runLoop forMode:NSDefaultRunLoopMode]; + stream.delegate = nil; + } +} + +- (BOOL)performRead { + if (!self.isVersionReceived) { + self.isVersionReceived = YES; + uint8_t versionByte = 0; + NSInteger bytesRead = [self.inStream read:&versionByte maxLength:sizeof(uint8_t)]; + if (bytesRead != sizeof(uint8_t) || kVersion != versionByte) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket010, + @"Version do not match. Received %d, Expecting %d", versionByte, + kVersion); + return NO; + } + } + + while (YES) { + BOOL isInputBufferValid = [self.inputBuffer length] > 0; + if (!isInputBufferValid) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket011, + @"Input buffer is not valid."); + return NO; + } + + if (![self.inStream hasBytesAvailable]) { + break; + } + + // try to read more data + uint8_t *unusedBufferPtr = (uint8_t *)self.inputBuffer.mutableBytes + self.inputBufferLength; + NSUInteger unusedBufferLength = [self.inputBuffer length] - self.inputBufferLength; + NSInteger bytesRead = [self.inStream read:unusedBufferPtr maxLength:unusedBufferLength]; + if (bytesRead <= 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket012, + @"Failed to read input stream. Bytes read %ld, Used buffer size %lu, " + @"Unused buffer size %lu", + _FIRMessaging_UL(bytesRead), _FIRMessaging_UL(self.inputBufferLength), + _FIRMessaging_UL(unusedBufferLength)); + break; + } + // did successfully read some more data + self.inputBufferLength += (NSUInteger)bytesRead; + + if ([self.inputBuffer length] <= self.inputBufferLength) { + // shouldn't be reading more than 1MB of data in one go + if ([self.inputBuffer length] + kBufferLengthIncrement > kMaxBufferLength) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket013, + @"Input buffer exceed 1M, disconnect socket"); + return NO; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket014, + @"Input buffer limit exceeded. Used input buffer size %lu, " + @"Total input buffer size %lu. No unused buffer left. " + @"Increase buffer size.", + _FIRMessaging_UL(self.inputBufferLength), + _FIRMessaging_UL([self.inputBuffer length])); + [self.inputBuffer increaseLengthBy:kBufferLengthIncrement]; + } + + while (self.inputBufferLength > 0 && [self.inputBuffer length] > 0) { + NSRange inputRange = NSMakeRange(0, self.inputBufferLength); + size_t protoBytes = 0; + // read the actual proto data coming in + FIRMessagingSecureSocketReadResult readResult = + [self processCurrentInputBuffer:[self.inputBuffer subdataWithRange:inputRange] + outOffset:&protoBytes]; + // Corrupt data encountered, stop processing. + if (readResult == kFIRMessagingSecureSocketReadResultCorrupt) { + return NO; + // Incomplete data, keep trying to read by loading more from the stream. + } else if (readResult == kFIRMessagingSecureSocketReadResultIncomplete) { + break; + } + // we have read (0, protoBytes) of data in the inputBuffer + if (protoBytes == self.inputBufferLength) { + // did completely read the buffer data can be reset for further processing + self.inputBufferLength = 0; + } else { + // delete processed bytes while maintaining the buffer size. + NSUInteger prevLength __unused = [self.inputBuffer length]; + // delete the processed bytes + [self.inputBuffer replaceBytesInRange:NSMakeRange(0, protoBytes) withBytes:NULL length:0]; + // reallocate more data + [self.inputBuffer increaseLengthBy:protoBytes]; + self.inputBufferLength -= protoBytes; + } + } + } + return YES; +} + +- (FIRMessagingSecureSocketReadResult)processCurrentInputBuffer:(NSData *)readData + outOffset:(size_t *)outOffset { + *outOffset = 0; + + FIRMessagingCodedInputStream *input = + [[FIRMessagingCodedInputStream alloc] initWithData:readData]; + int8_t rawTag; + if (![input readTag:&rawTag]) { + return kFIRMessagingSecureSocketReadResultIncomplete; + } + int32_t length; + if (![input readLength:&length]) { + return kFIRMessagingSecureSocketReadResultIncomplete; + } + // NOTE tag can be zero for |HeartbeatPing|, and length can be zero for |Close| proto + if (rawTag < 0 || length < 0) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket015, @"Buffer data corrupted."); + return kFIRMessagingSecureSocketReadResultCorrupt; + } + NSData *data = [input readDataWithLength:(uint32_t)length]; + if (data == nil) { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket016, + @"Incomplete data, buffered data length %ld, expected length %d", + _FIRMessaging_UL(self.inputBufferLength), length); + return kFIRMessagingSecureSocketReadResultIncomplete; + } + [self.delegate secureSocket:self didReceiveData:data withTag:rawTag]; + *outOffset = input.offset; + return kFIRMessagingSecureSocketReadResultSuccess; +} + +- (void)performWrite { + if (!self.isVersionSent) { + self.isVersionSent = YES; + uint8_t versionByte = kVersion; + [self.outStream write:&versionByte maxLength:sizeof(uint8_t)]; + } + + while (!self.packetQueue.isEmpty && self.outStream.hasSpaceAvailable) { + if (self.outputBuffer.length == 0) { + // serialize new packets only when the output buffer is flushed. + FIRMessagingPacket *packet = [self.packetQueue pop]; + self.currentRmqIdBeingSent = packet.rmqId; + self.currentProtoTypeBeingSent = packet.tag; + NSUInteger length = + SerializedSize(packet.tag) + SerializedSize((int)packet.data.length) + packet.data.length; + self.outputBuffer = [NSMutableData dataWithLength:length]; + GPBCodedOutputStream *output = [GPBCodedOutputStream streamWithData:self.outputBuffer]; + [output writeRawVarint32:packet.tag]; + [output writeBytesNoTag:packet.data]; + self.outputBufferLength = 0; + } + + // flush the output buffer. + NSInteger written = [self.outStream write:self.outputBuffer.bytes + self.outputBufferLength + maxLength:self.outputBuffer.length - self.outputBufferLength]; + if (written <= 0) { + continue; + } + self.outputBufferLength += (NSUInteger)written; + if (self.outputBufferLength >= self.outputBuffer.length) { + self.outputBufferLength = 0; + self.outputBuffer = nil; + [self.delegate secureSocket:self + didSendProtoWithTag:self.currentProtoTypeBeingSent + rmqId:self.currentRmqIdBeingSent]; + self.currentRmqIdBeingSent = nil; + self.currentProtoTypeBeingSent = kInvalidTag; + } + } +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h new file mode 100644 index 00000000..3d30bdb5 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class FIRMessagingRmqManager; + +/** + * Handle sync messages being received both via MCS and APNS. + */ +@interface FIRMessagingSyncMessageManager : NSObject + +/** + * Initialize sync message manager. + * + * @param rmqManager The RMQ manager on the client. + * + * @return Sync message manager. + */ +- (instancetype)initWithRmqManager:(FIRMessagingRmqManager *)rmqManager; + +/** + * Remove expired sync message from persistent store. Also removes messages that have + * been received both via APNS and MCS. + */ +- (void)removeExpiredSyncMessages; + +/** + * App did recive a sync message via APNS. + * + * @param message The sync message received. + * + * @return YES if the message is a duplicate of an already received sync message else NO. + */ +- (BOOL)didReceiveAPNSSyncMessage:(NSDictionary *)message; + +/** + * App did receive a sync message via MCS. + * + * @param message The sync message received. + * + * @return YES if the message is a duplicate of an already received sync message else NO. + */ +- (BOOL)didReceiveMCSSyncMessage:(NSDictionary *)message; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.m new file mode 100644 index 00000000..b38daab1 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.m @@ -0,0 +1,114 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h" + +#import "FirebaseMessaging/Sources/FIRMessagingConstants.h" +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h" +#import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" + +static const int64_t kDefaultSyncMessageTTL = 4 * 7 * 24 * 60 * 60; // 4 weeks +// 4 MB of free space is required to persist Sync messages +static const uint64_t kMinFreeDiskSpaceInMB = 1; + +@interface FIRMessagingSyncMessageManager () + +@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmqManager; + +@end + +@implementation FIRMessagingSyncMessageManager + +- (instancetype)init { + FIRMessagingInvalidateInitializer(); +} + +- (instancetype)initWithRmqManager:(FIRMessagingRmqManager *)rmqManager { + self = [super init]; + if (self) { + _rmqManager = rmqManager; + } + return self; +} + +- (void)removeExpiredSyncMessages { + [self.rmqManager deleteExpiredOrFinishedSyncMessages]; +} + +- (BOOL)didReceiveAPNSSyncMessage:(NSDictionary *)message { + return [self didReceiveSyncMessage:message viaAPNS:YES viaMCS:NO]; +} + +- (BOOL)didReceiveMCSSyncMessage:(NSDictionary *)message { + return [self didReceiveSyncMessage:message viaAPNS:NO viaMCS:YES]; +} + +- (BOOL)didReceiveSyncMessage:(NSDictionary *)message viaAPNS:(BOOL)viaAPNS viaMCS:(BOOL)viaMCS { + NSString *rmqID = message[kFIRMessagingMessageIDKey]; + if (![rmqID length]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager002, + @"Invalid nil rmqID for sync message."); + return NO; + } + + FIRMessagingPersistentSyncMessage *persistentMessage = + [self.rmqManager querySyncMessageWithRmqID:rmqID]; + + if (!persistentMessage) { + // Do not persist the new message if we don't have enough disk space + uint64_t freeDiskSpace = FIRMessagingGetFreeDiskSpaceInMB(); + if (freeDiskSpace < kMinFreeDiskSpaceInMB) { + return NO; + } + + int64_t expirationTime = [[self class] expirationTimeForSyncMessage:message]; + [self.rmqManager saveSyncMessageWithRmqID:rmqID + expirationTime:expirationTime + apnsReceived:viaAPNS + mcsReceived:viaMCS]; + return NO; + } + + if (viaAPNS && !persistentMessage.apnsReceived) { + persistentMessage.apnsReceived = YES; + [self.rmqManager updateSyncMessageViaAPNSWithRmqID:rmqID]; + } else if (viaMCS && !persistentMessage.mcsReceived) { + persistentMessage.mcsReceived = YES; + [self.rmqManager updateSyncMessageViaMCSWithRmqID:rmqID]; + } + + // Received message via both ways we can safely delete it. + if (persistentMessage.apnsReceived && persistentMessage.mcsReceived) { + [self.rmqManager deleteSyncMessageWithRmqID:rmqID]; + } + + // Already received this message either via MCS or APNS. + return YES; +} + ++ (int64_t)expirationTimeForSyncMessage:(NSDictionary *)message { + int64_t ttl = kDefaultSyncMessageTTL; + if (message[kFIRMessagingMessageSyncMessageTTLKey]) { + ttl = [message[kFIRMessagingMessageSyncMessageTTLKey] longLongValue]; + } + int64_t currentTime = FIRMessagingCurrentTimestampInSeconds(); + return currentTime + ttl; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicOperation.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicOperation.h new file mode 100644 index 00000000..6ae509ae --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicOperation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#import <FirebaseMessaging/FIRMessaging.h> + +#import "FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * An asynchronous NSOperation subclass which performs a single network request for a topic + * subscription operation. Once completed, it calls its provided completion handler. + */ +@interface FIRMessagingTopicOperation : NSOperation + +@property(nonatomic, readonly, copy) NSString *topic; +@property(nonatomic, readonly, assign) FIRMessagingTopicAction action; +@property(nonatomic, readonly, copy) NSString *token; +@property(nonatomic, readonly, copy, nullable) NSDictionary *options; + +- (instancetype)initWithTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + token:(NSString *)token + options:(nullable NSDictionary *)options + completion:(FIRMessagingTopicOperationCompletion)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicOperation.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicOperation.m new file mode 100644 index 00000000..8003bed6 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicOperation.m @@ -0,0 +1,249 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingTopicOperation.h" + +#import <FirebaseInstanceID/FIRInstanceID_Private.h> + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" +#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h" + +static NSString *const kFIRMessagingSubscribeServerHost = + @"https://iid.googleapis.com/iid/register"; + +NSString *FIRMessagingSubscriptionsServer() { + static NSString *serverHost = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *environment = [[NSProcessInfo processInfo] environment]; + NSString *customServerHost = environment[@"FCM_SERVER_ENDPOINT"]; + if (customServerHost.length) { + serverHost = customServerHost; + } else { + serverHost = kFIRMessagingSubscribeServerHost; + } + }); + return serverHost; +} + +@interface FIRMessagingTopicOperation () { + BOOL _isFinished; + BOOL _isExecuting; +} + +@property(nonatomic, readwrite, copy) NSString *topic; +@property(nonatomic, readwrite, assign) FIRMessagingTopicAction action; +@property(nonatomic, readwrite, copy) NSString *token; +@property(nonatomic, readwrite, copy) NSDictionary *options; +@property(nonatomic, readwrite, copy) FIRMessagingTopicOperationCompletion completion; + +@property(atomic, strong) NSURLSessionDataTask *dataTask; + +@end + +@implementation FIRMessagingTopicOperation + ++ (NSURLSession *)sharedSession { + static NSURLSession *subscriptionOperationSharedSession; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; + config.timeoutIntervalForResource = 60.0f; // 1 minute + subscriptionOperationSharedSession = [NSURLSession sessionWithConfiguration:config]; + subscriptionOperationSharedSession.sessionDescription = @"com.google.fcm.topics.session"; + }); + return subscriptionOperationSharedSession; +} + +- (instancetype)initWithTopic:(NSString *)topic + action:(FIRMessagingTopicAction)action + token:(NSString *)token + options:(NSDictionary *)options + completion:(FIRMessagingTopicOperationCompletion)completion { + if (self = [super init]) { + _topic = topic; + _action = action; + _token = token; + _options = options; + _completion = completion; + + _isExecuting = NO; + _isFinished = NO; + } + return self; +} + +- (void)dealloc { + _topic = nil; + _token = nil; + _completion = nil; +} + +- (BOOL)isAsynchronous { + return YES; +} + +- (BOOL)isExecuting { + return _isExecuting; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _isExecuting = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isFinished { + return _isFinished; +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _isFinished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)start { + if (self.isCancelled) { + NSError *error = [NSError + messagingErrorWithCode:kFIRMessagingErrorCodePubSubOperationIsCancelled + failureReason: + @"Failed to start the pubsub service as the topic operation is cancelled."]; + [self finishWithError:error]; + return; + } + + [self setExecuting:YES]; + + [self performSubscriptionChange]; +} + +- (void)finishWithError:(NSError *)error { + // Add a check to prevent this finish from being called more than once. + if (self.isFinished) { + return; + } + self.dataTask = nil; + if (self.completion) { + self.completion(error); + } + + [self setExecuting:NO]; + [self setFinished:YES]; +} + +- (void)cancel { + [super cancel]; + [self.dataTask cancel]; + NSError *error = [NSError messagingErrorWithCode:kFIRMessagingErrorCodePubSubOperationIsCancelled + failureReason:@"The topic operation is cancelled."]; + [self finishWithError:error]; +} + +- (void)performSubscriptionChange { + NSURL *url = [NSURL URLWithString:FIRMessagingSubscriptionsServer()]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + NSString *appIdentifier = FIRMessagingAppIdentifier(); + NSString *deviceAuthID = [FIRInstanceID instanceID].deviceAuthID; + NSString *secretToken = [FIRInstanceID instanceID].secretToken; + NSString *authString = [NSString stringWithFormat:@"AidLogin %@:%@", deviceAuthID, secretToken]; + [request setValue:authString forHTTPHeaderField:@"Authorization"]; + [request setValue:appIdentifier forHTTPHeaderField:@"app"]; + [request setValue:[FIRInstanceID instanceID].versionInfo forHTTPHeaderField:@"info"]; + + // Topic can contain special characters (like `%`) so encode the value. + NSCharacterSet *characterSet = [NSCharacterSet URLQueryAllowedCharacterSet]; + NSString *encodedTopic = + [self.topic stringByAddingPercentEncodingWithAllowedCharacters:characterSet]; + if (encodedTopic == nil) { + // The transformation was somehow not possible, so use the original topic. + FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicOptionTopicEncodingFailed, + @"Unable to encode the topic '%@' during topic subscription change. " + @"Please ensure that the topic name contains only valid characters.", + self.topic); + encodedTopic = self.topic; + } + + NSMutableString *content = [NSMutableString + stringWithFormat:@"sender=%@&app=%@&device=%@&" + @"app_ver=%@&X-gcm.topic=%@&X-scope=%@", + self.token, appIdentifier, deviceAuthID, FIRMessagingCurrentAppVersion(), + encodedTopic, encodedTopic]; + + if (self.action == FIRMessagingTopicActionUnsubscribe) { + [content appendString:@"&delete=true"]; + } + + FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTopicOption000, @"Topic subscription request: %@", + content); + + request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; + [request setHTTPMethod:@"POST"]; + + FIRMessaging_WEAKIFY(self) void (^requestHandler)(NSData *, NSURLResponse *, NSError *) = + ^(NSData *data, NSURLResponse *URLResponse, NSError *error) { + FIRMessaging_STRONGIFY(self) if (error) { + // Our operation could have been cancelled, which would result in our data task's error + // being NSURLErrorCancelled + if (error.code == NSURLErrorCancelled) { + // We would only have been cancelled in the -cancel method, which will call finish for + // us so just return and do nothing. + return; + } + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption001, + @"Device registration HTTP fetch error. Error Code: %ld", + (long)error.code); + [self finishWithError:error]; + return; + } + NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (response.length == 0) { + NSString *failureReason = @"Invalid registration response - zero length."; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOperationEmptyResponse, @"%@", + failureReason); + [self finishWithError:[NSError messagingErrorWithCode:kFIRMessagingErrorCodeUnknown + failureReason:failureReason]]; + return; + } + NSArray *parts = [response componentsSeparatedByString:@"="]; + if (![parts[0] isEqualToString:@"token"] || parts.count <= 1) { + NSString *failureReason = [NSString + stringWithFormat:@"Invalid registration response :'%@'. It is missing 'token' field.", + response]; + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption002, @"%@", failureReason); + [self finishWithError:[NSError messagingErrorWithCode:kFIRMessagingErrorCodeUnknown + failureReason:failureReason]]; + return; + } + [self finishWithError:nil]; + }; + + NSURLSession *urlSession = [FIRMessagingTopicOperation sharedSession]; + + self.dataTask = [urlSession dataTaskWithRequest:request completionHandler:requestHandler]; + NSString *description; + if (_action == FIRMessagingTopicActionSubscribe) { + description = [NSString stringWithFormat:@"com.google.fcm.topics.subscribe: %@", _topic]; + } else { + description = [NSString stringWithFormat:@"com.google.fcm.topics.unsubscribe: %@", _topic]; + } + self.dataTask.taskDescription = description; + [self.dataTask resume]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h new file mode 100644 index 00000000..030b3fff --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingTopicsCommon.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents the action taken on a subscription topic. + */ +typedef NS_ENUM(NSInteger, FIRMessagingTopicAction) { + FIRMessagingTopicActionSubscribe, + FIRMessagingTopicActionUnsubscribe +}; + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingUtilities.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingUtilities.h new file mode 100644 index 00000000..9209348e --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingUtilities.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +typedef NS_ENUM(int8_t, FIRMessagingProtoTag) { + kFIRMessagingProtoTagInvalid = -1, + kFIRMessagingProtoTagHeartbeatPing = 0, + kFIRMessagingProtoTagHeartbeatAck = 1, + kFIRMessagingProtoTagLoginRequest = 2, + kFIRMessagingProtoTagLoginResponse = 3, + kFIRMessagingProtoTagClose = 4, + kFIRMessagingProtoTagIqStanza = 7, + kFIRMessagingProtoTagDataMessageStanza = 8, +}; + +@class GPBMessage; + +#pragma mark - Protocol Buffers + +FOUNDATION_EXPORT FIRMessagingProtoTag FIRMessagingGetTagForProto(GPBMessage *protoClass); +FOUNDATION_EXPORT Class FIRMessagingGetClassForTag(FIRMessagingProtoTag tag); + +#pragma mark - MCS + +FOUNDATION_EXPORT NSString *FIRMessagingGetRmq2Id(GPBMessage *proto); +FOUNDATION_EXPORT void FIRMessagingSetRmq2Id(GPBMessage *proto, NSString *pID); +FOUNDATION_EXPORT int FIRMessagingGetLastStreamId(GPBMessage *proto); +FOUNDATION_EXPORT void FIRMessagingSetLastStreamId(GPBMessage *proto, int sid); + +#pragma mark - Time + +FOUNDATION_EXPORT int64_t FIRMessagingCurrentTimestampInSeconds(void); +FOUNDATION_EXPORT int64_t FIRMessagingCurrentTimestampInMilliseconds(void); + +#pragma mark - App Info + +FOUNDATION_EXPORT NSString *FIRMessagingCurrentAppVersion(void); +FOUNDATION_EXPORT NSString *FIRMessagingAppIdentifier(void); + +#pragma mark - Others + +FOUNDATION_EXPORT uint64_t FIRMessagingGetFreeDiskSpaceInMB(void); +FOUNDATION_EXPORT NSSearchPathDirectory FIRMessagingSupportedDirectory(void); diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingUtilities.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingUtilities.m new file mode 100644 index 00000000..708c01a0 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingUtilities.m @@ -0,0 +1,201 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h" + +#import "FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h" + +#import "FirebaseMessaging/Sources/FIRMessagingLogger.h" + +#import "GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h" + +// Convert the macro to a string +#define STR_EXPAND(x) #x +#define STR(x) STR_EXPAND(x) + +static const uint64_t kBytesToMegabytesDivisor = 1024 * 1024LL; + +#pragma mark - Protocol Buffers + +FIRMessagingProtoTag FIRMessagingGetTagForProto(GPBMessage *proto) { + if ([proto isKindOfClass:[GtalkHeartbeatPing class]]) { + return kFIRMessagingProtoTagHeartbeatPing; + } else if ([proto isKindOfClass:[GtalkHeartbeatAck class]]) { + return kFIRMessagingProtoTagHeartbeatAck; + } else if ([proto isKindOfClass:[GtalkLoginRequest class]]) { + return kFIRMessagingProtoTagLoginRequest; + } else if ([proto isKindOfClass:[GtalkLoginResponse class]]) { + return kFIRMessagingProtoTagLoginResponse; + } else if ([proto isKindOfClass:[GtalkClose class]]) { + return kFIRMessagingProtoTagClose; + } else if ([proto isKindOfClass:[GtalkIqStanza class]]) { + return kFIRMessagingProtoTagIqStanza; + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + return kFIRMessagingProtoTagDataMessageStanza; + } + return kFIRMessagingProtoTagInvalid; +} + +Class FIRMessagingGetClassForTag(FIRMessagingProtoTag tag) { + switch (tag) { + case kFIRMessagingProtoTagHeartbeatPing: + return GtalkHeartbeatPing.class; + case kFIRMessagingProtoTagHeartbeatAck: + return GtalkHeartbeatAck.class; + case kFIRMessagingProtoTagLoginRequest: + return GtalkLoginRequest.class; + case kFIRMessagingProtoTagLoginResponse: + return GtalkLoginResponse.class; + case kFIRMessagingProtoTagClose: + return GtalkClose.class; + case kFIRMessagingProtoTagIqStanza: + return GtalkIqStanza.class; + case kFIRMessagingProtoTagDataMessageStanza: + return GtalkDataMessageStanza.class; + case kFIRMessagingProtoTagInvalid: + return NSNull.class; + } + return NSNull.class; +} + +#pragma mark - MCS + +NSString *FIRMessagingGetRmq2Id(GPBMessage *proto) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + if (((GtalkIqStanza *)proto).hasPersistentId) { + return ((GtalkIqStanza *)proto).persistentId; + } + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + if (((GtalkDataMessageStanza *)proto).hasPersistentId) { + return ((GtalkDataMessageStanza *)proto).persistentId; + } + } + return nil; +} + +void FIRMessagingSetRmq2Id(GPBMessage *proto, NSString *pID) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + ((GtalkIqStanza *)proto).persistentId = pID; + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + ((GtalkDataMessageStanza *)proto).persistentId = pID; + } +} + +int FIRMessagingGetLastStreamId(GPBMessage *proto) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + if (((GtalkIqStanza *)proto).hasLastStreamIdReceived) { + return ((GtalkIqStanza *)proto).lastStreamIdReceived; + } + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + if (((GtalkDataMessageStanza *)proto).hasLastStreamIdReceived) { + return ((GtalkDataMessageStanza *)proto).lastStreamIdReceived; + } + } else if ([proto isKindOfClass:[GtalkHeartbeatPing class]]) { + if (((GtalkHeartbeatPing *)proto).hasLastStreamIdReceived) { + return ((GtalkHeartbeatPing *)proto).lastStreamIdReceived; + } + } else if ([proto isKindOfClass:[GtalkHeartbeatAck class]]) { + if (((GtalkHeartbeatAck *)proto).hasLastStreamIdReceived) { + return ((GtalkHeartbeatAck *)proto).lastStreamIdReceived; + } + } + return -1; +} + +void FIRMessagingSetLastStreamId(GPBMessage *proto, int sid) { + if ([proto isKindOfClass:[GtalkIqStanza class]]) { + ((GtalkIqStanza *)proto).lastStreamIdReceived = sid; + } else if ([proto isKindOfClass:[GtalkDataMessageStanza class]]) { + ((GtalkDataMessageStanza *)proto).lastStreamIdReceived = sid; + } else if ([proto isKindOfClass:[GtalkHeartbeatPing class]]) { + ((GtalkHeartbeatPing *)proto).lastStreamIdReceived = sid; + } else if ([proto isKindOfClass:[GtalkHeartbeatAck class]]) { + ((GtalkHeartbeatAck *)proto).lastStreamIdReceived = sid; + } +} + +#pragma mark - Time + +int64_t FIRMessagingCurrentTimestampInSeconds(void) { + return (int64_t)[[NSDate date] timeIntervalSince1970]; +} + +int64_t FIRMessagingCurrentTimestampInMilliseconds(void) { + return (int64_t)(FIRMessagingCurrentTimestampInSeconds() * 1000.0); +} + +#pragma mark - App Info + +NSString *FIRMessagingCurrentAppVersion(void) { + NSString *version = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"]; + if (![version length]) { + FIRMessagingLoggerError(kFIRMessagingMessageCodeUtilities000, + @"Could not find current app version"); + return @""; + } + return version; +} + +NSString *FIRMessagingBundleIDByRemovingLastPartFrom(NSString *bundleID) { + NSString *bundleIDComponentsSeparator = @"."; + + NSMutableArray<NSString *> *bundleIDComponents = + [[bundleID componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy]; + [bundleIDComponents removeLastObject]; + + return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator]; +} + +NSString *FIRMessagingAppIdentifier(void) { + NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; +#if TARGET_OS_WATCH + // The code is running in watchKit extension target but the actually bundleID is in the watchKit + // target. So we need to remove the last part of the bundle ID in watchKit extension to match + // the one in watchKit target. + return FIRMessagingBundleIDByRemovingLastPartFrom(bundleID); +#else + return bundleID; +#endif +} + +uint64_t FIRMessagingGetFreeDiskSpaceInMB(void) { + NSError *error; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + + NSDictionary *attributesMap = + [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] + error:&error]; + if (attributesMap) { + uint64_t totalSizeInBytes __unused = [attributesMap[NSFileSystemSize] longLongValue]; + uint64_t freeSizeInBytes = [attributesMap[NSFileSystemFreeSize] longLongValue]; + FIRMessagingLoggerDebug( + kFIRMessagingMessageCodeUtilities001, @"Device has capacity %llu MB with %llu MB free.", + totalSizeInBytes / kBytesToMegabytesDivisor, freeSizeInBytes / kBytesToMegabytesDivisor); + return ((double)freeSizeInBytes) / kBytesToMegabytesDivisor; + } else { + FIRMessagingLoggerError(kFIRMessagingMessageCodeUtilities002, + @"Error in retreiving device's free memory %@", error); + return 0; + } +} + +NSSearchPathDirectory FIRMessagingSupportedDirectory(void) { +#if TARGET_OS_TV + return NSCachesDirectory; +#else + return NSApplicationSupportDirectory; +#endif +} diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingVersionUtilities.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingVersionUtilities.h new file mode 100644 index 00000000..7d7014e1 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingVersionUtilities.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +/** + * Parsing utility for FIRMessaging Library versions. FIRMessaging Library follows semantic + * versioning. This provides utilities to parse the library versions to enable features and do + * updates based on appropriate library versions. + * + * Some example semantic versions are 1.0.1, 2.1.0, 2.1.1, 2.2.0-alpha1, 2.2.1-beta1 + */ + +FOUNDATION_EXPORT NSString *FIRMessagingCurrentLibraryVersion(void); +/// Returns the current Major version of FIRMessaging library. +FOUNDATION_EXPORT int FIRMessagingCurrentLibraryVersionMajor(void); +/// Returns the current Minor version of FIRMessaging library. +FOUNDATION_EXPORT int FIRMessagingCurrentLibraryVersionMinor(void); +/// Returns the current Patch version of FIRMessaging library. +FOUNDATION_EXPORT int FIRMessagingCurrentLibraryVersionPatch(void); +/// Returns YES if current library version is `beta` else NO. +FOUNDATION_EXPORT BOOL FIRMessagingCurrentLibraryVersionIsBeta(void); diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingVersionUtilities.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingVersionUtilities.m new file mode 100644 index 00000000..af3997c2 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessagingVersionUtilities.m @@ -0,0 +1,86 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseMessaging/Sources/FIRMessagingVersionUtilities.h" + +#import "FirebaseMessaging/Sources/FIRMessagingDefines.h" + +// Convert the macro to a string +#define STR_EXPAND(x) #x +#define STR(x) STR_EXPAND(x) + +static NSString *const kSemanticVersioningSeparator = @"."; +static NSString *const kBetaVersionPrefix = @"-beta"; + +static NSString *libraryVersion; +static int majorVersion; +static int minorVersion; +static int patchVersion; +static int betaVersion; + +void FIRMessagingParseCurrentLibraryVersion(void) { + static NSArray *allVersions; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableString *daylightVersion = + [NSMutableString stringWithUTF8String:STR(FIRMessaging_LIB_VERSION)]; + // Parse versions + // major, minor, patch[-beta#] + allVersions = [daylightVersion componentsSeparatedByString:kSemanticVersioningSeparator]; + if (allVersions.count == 3) { + majorVersion = [allVersions[0] intValue]; + minorVersion = [allVersions[1] intValue]; + + // Parse patch and beta versions + NSArray *patchAndBetaVersion = + [allVersions[2] componentsSeparatedByString:kBetaVersionPrefix]; + if (patchAndBetaVersion.count == 2) { + patchVersion = [patchAndBetaVersion[0] intValue]; + betaVersion = [patchAndBetaVersion[1] intValue]; + } else if (patchAndBetaVersion.count == 1) { + patchVersion = [patchAndBetaVersion[0] intValue]; + } + } + + // Copy library version + libraryVersion = [daylightVersion copy]; + }); +} + +NSString *FIRMessagingCurrentLibraryVersion(void) { + FIRMessagingParseCurrentLibraryVersion(); + return libraryVersion; +} + +int FIRMessagingCurrentLibraryVersionMajor(void) { + FIRMessagingParseCurrentLibraryVersion(); + return majorVersion; +} + +int FIRMessagingCurrentLibraryVersionMinor(void) { + FIRMessagingParseCurrentLibraryVersion(); + return minorVersion; +} + +int FIRMessagingCurrentLibraryVersionPatch(void) { + FIRMessagingParseCurrentLibraryVersion(); + return patchVersion; +} + +BOOL FIRMessagingCurrentLibraryVersionIsBeta(void) { + FIRMessagingParseCurrentLibraryVersion(); + return betaVersion > 0; +} diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessaging_Private.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessaging_Private.h new file mode 100644 index 00000000..1aa7bd7b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FIRMessaging_Private.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessaging.h> + +@class FIRMessagingClient; +@class FIRMessagingPubSub; + +typedef NS_ENUM(int8_t, FIRMessagingNetworkStatus) { + kFIRMessagingReachabilityNotReachable = 0, + kFIRMessagingReachabilityReachableViaWiFi, + kFIRMessagingReachabilityReachableViaWWAN, +}; + +FOUNDATION_EXPORT NSString *const kFIRMessagingPlistAutoInitEnabled; +FOUNDATION_EXPORT NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled; +FOUNDATION_EXPORT NSString *const kFIRMessagingUserDefaultsKeyUseMessagingDelegate; +FOUNDATION_EXPORT NSString *const kFIRMessagingPlistUseMessagingDelegate; + +@interface FIRMessagingRemoteMessage () + +@property(nonatomic, copy) NSString *messageID; +@property(nonatomic, strong) NSDictionary *appData; + +@end + +@interface FIRMessaging () + +#pragma mark - Private API + +- (NSString *)defaultFcmToken; +- (FIRMessagingClient *)client; +- (FIRMessagingPubSub *)pubsub; + +// Create a sample message to be sent over the wire using FIRMessaging. Look at +// FIRMessagingService.h to see what each param signifies. ++ (NSMutableDictionary *)createFIRMessagingMessageWithMessage:(NSDictionary *)message + to:(NSString *)to + withID:(NSString *)msgID + timeToLive:(int64_t)ttl + delay:(int)delay; + +- (BOOL)isNetworkAvailable; +- (FIRMessagingNetworkStatus)networkType; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FirebaseMessaging.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FirebaseMessaging.h new file mode 100644 index 00000000..69a5050e --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/FirebaseMessaging.h @@ -0,0 +1,17 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessaging.h> diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSDictionary+FIRMessaging.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSDictionary+FIRMessaging.h new file mode 100644 index 00000000..fe14451b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSDictionary+FIRMessaging.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@interface NSDictionary (FIRMessaging) + +/** + * Returns a string representation for the given dictionary. Assumes that all + * keys and values are strings. + * + * @return A string representation of all keys and values in the dictionary. + * The returned string is not pretty-printed. + */ +- (NSString *)fcm_string; + +/** + * Check if the dictionary has any non-string keys or values. + * + * @return YES if the dictionary has any non-string keys or values else NO. + */ +- (BOOL)fcm_hasNonStringKeysOrValues; + +/** + * Trims all (key, value) pair in a dictionary that are not strings. + * + * @return A new copied dictionary with all the non-string keys or values + * removed from the original dictionary. + */ +- (NSDictionary *)fcm_trimNonStringValues; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSDictionary+FIRMessaging.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSDictionary+FIRMessaging.m new file mode 100644 index 00000000..6e696751 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSDictionary+FIRMessaging.m @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "NSDictionary+FIRMessaging.h" + +@implementation NSDictionary (FIRMessaging) + +- (NSString *)fcm_string { + NSMutableString *dictAsString = [NSMutableString string]; + NSString *separator = @"|"; + for (id key in self) { + id value = self[key]; + if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) { + [dictAsString appendFormat:@"%@:%@%@", key, value, separator]; + } + } + // remove the last separator + if ([dictAsString length]) { + [dictAsString deleteCharactersInRange:NSMakeRange(dictAsString.length - 1, 1)]; + } + return [dictAsString copy]; +} + +- (BOOL)fcm_hasNonStringKeysOrValues { + for (id key in self) { + id value = self[key]; + if (![key isKindOfClass:[NSString class]] || ![value isKindOfClass:[NSString class]]) { + return YES; + } + } + return NO; +} + +- (NSDictionary *)fcm_trimNonStringValues { + NSMutableDictionary *trimDictionary = [NSMutableDictionary dictionaryWithCapacity:self.count]; + for (id key in self) { + id value = self[key]; + if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) { + trimDictionary[(NSString *)key] = value; + } + } + return trimDictionary; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSError+FIRMessaging.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSError+FIRMessaging.h new file mode 100644 index 00000000..3f751a9a --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSError+FIRMessaging.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString *const kFIRMessagingDomain; + +// FIRMessaging Internal Error Code +typedef NS_ENUM(NSUInteger, FIRMessagingErrorCode) { + kFIRMessagingErrorCodeUnknown = 0, + + kFIRMessagingErrorCodeNetwork = 4, + + kFIRMessagingErrorCodeInvalidRequest = 7, + + kFIRMessagingErrorCodeInvalidTopicName = 8, + + // FIRMessaging generic errors + kFIRMessagingErrorCodeMissingDeviceID = 501, + + // Upstream send errors + kFIRMessagingErrorCodeServiceNotAvailable = 1001, + kFIRMessagingErrorCodeMissingTo = 1003, + kFIRMessagingErrorCodeSave = 1004, + kFIRMessagingErrorCodeSizeExceeded = 1005, + + // Already connected with MCS + kFIRMessagingErrorCodeAlreadyConnected = 2001, + + // PubSub errors + kFIRMessagingErrorCodePubSubClientNotSetup = 3004, + kFIRMessagingErrorCodePubSubOperationIsCancelled = 3005, +}; + +@interface NSError (FIRMessaging) + ++ (NSError *)messagingErrorWithCode:(FIRMessagingErrorCode)fcmErrorCode + failureReason:(NSString *)failureReason; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSError+FIRMessaging.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSError+FIRMessaging.m new file mode 100644 index 00000000..b88d8a75 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/NSError+FIRMessaging.m @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "NSError+FIRMessaging.h" + +NSString *const kFIRMessagingDomain = @"com.google.fcm"; + +@implementation NSError (FIRMessaging) + ++ (NSError *)messagingErrorWithCode:(FIRMessagingErrorCode)errorCode + failureReason:(NSString *)failureReason { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + userInfo[NSLocalizedFailureReasonErrorKey] = failureReason; + return [NSError errorWithDomain:kFIRMessagingDomain code:errorCode userInfo:userInfo]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h new file mode 100644 index 00000000..46d2d9ce --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.h @@ -0,0 +1,1374 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_core.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import <Protobuf/GPBProtocolBuffers.h> +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GtalkAppData; +@class GtalkCellTower; +@class GtalkClientEvent; +@class GtalkErrorInfo; +@class GtalkExtension; +@class GtalkHeartbeatConfig; +@class GtalkHeartbeatStat; +@class GtalkPresenceStanza; +@class GtalkSetting; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GtalkLoginRequest_AuthService + +typedef GPB_ENUM(GtalkLoginRequest_AuthService) { + GtalkLoginRequest_AuthService_Mail = 0, + GtalkLoginRequest_AuthService_AndroidCloudToDeviceMessage = 1, + GtalkLoginRequest_AuthService_AndroidId = 2, +}; + +GPBEnumDescriptor *GtalkLoginRequest_AuthService_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkLoginRequest_AuthService_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkMessageStanza_MessageType + +typedef GPB_ENUM(GtalkMessageStanza_MessageType) { + GtalkMessageStanza_MessageType_Normal = 0, + GtalkMessageStanza_MessageType_Chat = 1, + GtalkMessageStanza_MessageType_Groupchat = 2, + GtalkMessageStanza_MessageType_Headline = 3, + GtalkMessageStanza_MessageType_Error = 4, +}; + +GPBEnumDescriptor *GtalkMessageStanza_MessageType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkMessageStanza_MessageType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_PresenceType + +typedef GPB_ENUM(GtalkPresenceStanza_PresenceType) { + GtalkPresenceStanza_PresenceType_Unavailable = 0, + GtalkPresenceStanza_PresenceType_Subscribe = 1, + GtalkPresenceStanza_PresenceType_Subscribed = 2, + GtalkPresenceStanza_PresenceType_Unsubscribe = 3, + GtalkPresenceStanza_PresenceType_Unsubscribed = 4, + GtalkPresenceStanza_PresenceType_Probe = 5, + GtalkPresenceStanza_PresenceType_Error = 6, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_PresenceType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_PresenceType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_ShowType + +typedef GPB_ENUM(GtalkPresenceStanza_ShowType) { + GtalkPresenceStanza_ShowType_Away = 0, + GtalkPresenceStanza_ShowType_Chat = 1, + GtalkPresenceStanza_ShowType_Dnd = 2, + GtalkPresenceStanza_ShowType_Xa = 3, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_ShowType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_ShowType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_ClientType + +typedef GPB_ENUM(GtalkPresenceStanza_ClientType) { + GtalkPresenceStanza_ClientType_Mobile = 0, + GtalkPresenceStanza_ClientType_Android = 1, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_ClientType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_ClientType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPresenceStanza_CapabilitiesFlags + +typedef GPB_ENUM(GtalkPresenceStanza_CapabilitiesFlags) { + GtalkPresenceStanza_CapabilitiesFlags_HasVoiceV1 = 1, + GtalkPresenceStanza_CapabilitiesFlags_HasVideoV1 = 2, + GtalkPresenceStanza_CapabilitiesFlags_HasCameraV1 = 4, + GtalkPresenceStanza_CapabilitiesFlags_HasPmucV1 = 8, +}; + +GPBEnumDescriptor *GtalkPresenceStanza_CapabilitiesFlags_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPresenceStanza_CapabilitiesFlags_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkBatchPresenceStanza_Type + +typedef GPB_ENUM(GtalkBatchPresenceStanza_Type) { + GtalkBatchPresenceStanza_Type_Get = 0, + GtalkBatchPresenceStanza_Type_Set = 1, +}; + +GPBEnumDescriptor *GtalkBatchPresenceStanza_Type_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkBatchPresenceStanza_Type_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkIqStanza_IqType + +typedef GPB_ENUM(GtalkIqStanza_IqType) { + GtalkIqStanza_IqType_Get = 0, + GtalkIqStanza_IqType_Set = 1, + GtalkIqStanza_IqType_Result = 2, + GtalkIqStanza_IqType_Error = 3, +}; + +GPBEnumDescriptor *GtalkIqStanza_IqType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkIqStanza_IqType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkClientEvent_Type + +typedef GPB_ENUM(GtalkClientEvent_Type) { + GtalkClientEvent_Type_Unknown = 0, + GtalkClientEvent_Type_DiscardedEvents = 1, + GtalkClientEvent_Type_FailedConnection = 2, + GtalkClientEvent_Type_SuccessfulConnection = 3, + GtalkClientEvent_Type_McsReconnectRequest = 4, + GtalkClientEvent_Type_FailedSocketCreationMcsReconnect = 5, + GtalkClientEvent_Type_McsReconnectLimited = 6, +}; + +GPBEnumDescriptor *GtalkClientEvent_Type_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkClientEvent_Type_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkClientEvent_McsReconnectAction + +typedef GPB_ENUM(GtalkClientEvent_McsReconnectAction) { + GtalkClientEvent_McsReconnectAction_None = 0, + GtalkClientEvent_McsReconnectAction_NotConnected = 1, + GtalkClientEvent_McsReconnectAction_TooSoon = 2, +}; + +GPBEnumDescriptor *GtalkClientEvent_McsReconnectAction_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkClientEvent_McsReconnectAction_IsValidValue(int32_t value); + +#pragma mark - GtalkGtalkCoreRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GtalkGtalkCoreRoot : GPBRootObject +@end + +#pragma mark - GtalkHeartbeatPing + +typedef GPB_ENUM(GtalkHeartbeatPing_FieldNumber) { + GtalkHeartbeatPing_FieldNumber_StreamId = 1, + GtalkHeartbeatPing_FieldNumber_LastStreamIdReceived = 2, + GtalkHeartbeatPing_FieldNumber_Status = 3, + GtalkHeartbeatPing_FieldNumber_CellTower = 4, + GtalkHeartbeatPing_FieldNumber_IntervalMs = 5, +}; + +@interface GtalkHeartbeatPing : GPBMessage + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkHeartbeatAck + +typedef GPB_ENUM(GtalkHeartbeatAck_FieldNumber) { + GtalkHeartbeatAck_FieldNumber_StreamId = 1, + GtalkHeartbeatAck_FieldNumber_LastStreamIdReceived = 2, + GtalkHeartbeatAck_FieldNumber_Status = 3, + GtalkHeartbeatAck_FieldNumber_CellTower = 4, + GtalkHeartbeatAck_FieldNumber_IntervalMs = 5, +}; + +@interface GtalkHeartbeatAck : GPBMessage + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkErrorInfo + +typedef GPB_ENUM(GtalkErrorInfo_FieldNumber) { + GtalkErrorInfo_FieldNumber_Code = 1, + GtalkErrorInfo_FieldNumber_Message = 2, + GtalkErrorInfo_FieldNumber_Type = 3, + GtalkErrorInfo_FieldNumber_Extension = 4, +}; + +@interface GtalkErrorInfo : GPBMessage + + +@property(nonatomic, readwrite) int32_t code; + +@property(nonatomic, readwrite) BOOL hasCode; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *message; +/** Test to see if @c message has been set. */ +@property(nonatomic, readwrite) BOOL hasMessage; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *type; +/** Test to see if @c type has been set. */ +@property(nonatomic, readwrite) BOOL hasType; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkExtension *extension; +/** Test to see if @c extension has been set. */ +@property(nonatomic, readwrite) BOOL hasExtension; + +@end + +#pragma mark - GtalkSetting + +typedef GPB_ENUM(GtalkSetting_FieldNumber) { + GtalkSetting_FieldNumber_Name = 1, + GtalkSetting_FieldNumber_Value = 2, +}; + +@interface GtalkSetting : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; +/** Test to see if @c name has been set. */ +@property(nonatomic, readwrite) BOOL hasName; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *value; +/** Test to see if @c value has been set. */ +@property(nonatomic, readwrite) BOOL hasValue; + +@end + +#pragma mark - GtalkHeartbeatStat + +typedef GPB_ENUM(GtalkHeartbeatStat_FieldNumber) { + GtalkHeartbeatStat_FieldNumber_Ip = 1, + GtalkHeartbeatStat_FieldNumber_Timeout = 2, + GtalkHeartbeatStat_FieldNumber_IntervalMs = 3, +}; + +@interface GtalkHeartbeatStat : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ip; +/** Test to see if @c ip has been set. */ +@property(nonatomic, readwrite) BOOL hasIp; + + +@property(nonatomic, readwrite) BOOL timeout; + +@property(nonatomic, readwrite) BOOL hasTimeout; + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkHeartbeatConfig + +typedef GPB_ENUM(GtalkHeartbeatConfig_FieldNumber) { + GtalkHeartbeatConfig_FieldNumber_UploadStat = 1, + GtalkHeartbeatConfig_FieldNumber_Ip = 2, + GtalkHeartbeatConfig_FieldNumber_IntervalMs = 3, +}; + +@interface GtalkHeartbeatConfig : GPBMessage + + +@property(nonatomic, readwrite) BOOL uploadStat; + +@property(nonatomic, readwrite) BOOL hasUploadStat; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ip; +/** Test to see if @c ip has been set. */ +@property(nonatomic, readwrite) BOOL hasIp; + + +@property(nonatomic, readwrite) int32_t intervalMs; + +@property(nonatomic, readwrite) BOOL hasIntervalMs; +@end + +#pragma mark - GtalkLoginRequest + +typedef GPB_ENUM(GtalkLoginRequest_FieldNumber) { + GtalkLoginRequest_FieldNumber_Id_p = 1, + GtalkLoginRequest_FieldNumber_Domain = 2, + GtalkLoginRequest_FieldNumber_User = 3, + GtalkLoginRequest_FieldNumber_Resource = 4, + GtalkLoginRequest_FieldNumber_AuthToken = 5, + GtalkLoginRequest_FieldNumber_DeviceId = 6, + GtalkLoginRequest_FieldNumber_LastRmqId = 7, + GtalkLoginRequest_FieldNumber_SettingArray = 8, + GtalkLoginRequest_FieldNumber_ReceivedPersistentIdArray = 10, + GtalkLoginRequest_FieldNumber_IncludeStreamIds = 11, + GtalkLoginRequest_FieldNumber_HeartbeatStat = 13, + GtalkLoginRequest_FieldNumber_UseRmq2 = 14, + GtalkLoginRequest_FieldNumber_AccountId = 15, + GtalkLoginRequest_FieldNumber_AuthService = 16, + GtalkLoginRequest_FieldNumber_NetworkType = 17, + GtalkLoginRequest_FieldNumber_Status = 18, + GtalkLoginRequest_FieldNumber_TokenVersionInfo = 19, + GtalkLoginRequest_FieldNumber_CellTower = 20, + GtalkLoginRequest_FieldNumber_GcmStartTimeMs = 21, + GtalkLoginRequest_FieldNumber_ClientEventArray = 22, + GtalkLoginRequest_FieldNumber_OnFallback = 23, + GtalkLoginRequest_FieldNumber_NoPendingUpstream = 24, + GtalkLoginRequest_FieldNumber_ReconnectRequestId = 25, +}; + +@interface GtalkLoginRequest : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *domain; +/** Test to see if @c domain has been set. */ +@property(nonatomic, readwrite) BOOL hasDomain; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *resource; +/** Test to see if @c resource has been set. */ +@property(nonatomic, readwrite) BOOL hasResource; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *authToken; +/** Test to see if @c authToken has been set. */ +@property(nonatomic, readwrite) BOOL hasAuthToken; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *deviceId; +/** Test to see if @c deviceId has been set. */ +@property(nonatomic, readwrite) BOOL hasDeviceId; + + +@property(nonatomic, readwrite) int64_t lastRmqId; + +@property(nonatomic, readwrite) BOOL hasLastRmqId; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkSetting*> *settingArray; +/** The number of items in @c settingArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger settingArray_Count; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *receivedPersistentIdArray; +/** The number of items in @c receivedPersistentIdArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger receivedPersistentIdArray_Count; + + +@property(nonatomic, readwrite) BOOL includeStreamIds; + +@property(nonatomic, readwrite) BOOL hasIncludeStreamIds; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkHeartbeatStat *heartbeatStat; +/** Test to see if @c heartbeatStat has been set. */ +@property(nonatomic, readwrite) BOOL hasHeartbeatStat; + + +@property(nonatomic, readwrite) BOOL useRmq2; + +@property(nonatomic, readwrite) BOOL hasUseRmq2; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; + +@property(nonatomic, readwrite) GtalkLoginRequest_AuthService authService; + +@property(nonatomic, readwrite) BOOL hasAuthService; + +@property(nonatomic, readwrite) int32_t networkType; + +@property(nonatomic, readwrite) BOOL hasNetworkType; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *tokenVersionInfo; +/** Test to see if @c tokenVersionInfo has been set. */ +@property(nonatomic, readwrite) BOOL hasTokenVersionInfo; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) uint64_t gcmStartTimeMs; + +@property(nonatomic, readwrite) BOOL hasGcmStartTimeMs; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkClientEvent*> *clientEventArray; +/** The number of items in @c clientEventArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger clientEventArray_Count; + + +@property(nonatomic, readwrite) BOOL onFallback; + +@property(nonatomic, readwrite) BOOL hasOnFallback; + +@property(nonatomic, readwrite) BOOL noPendingUpstream; + +@property(nonatomic, readwrite) BOOL hasNoPendingUpstream; + +@property(nonatomic, readwrite) int32_t reconnectRequestId; + +@property(nonatomic, readwrite) BOOL hasReconnectRequestId; +@end + +#pragma mark - GtalkLoginResponse + +typedef GPB_ENUM(GtalkLoginResponse_FieldNumber) { + GtalkLoginResponse_FieldNumber_Id_p = 1, + GtalkLoginResponse_FieldNumber_Jid = 2, + GtalkLoginResponse_FieldNumber_Error = 3, + GtalkLoginResponse_FieldNumber_SettingArray = 4, + GtalkLoginResponse_FieldNumber_StreamId = 5, + GtalkLoginResponse_FieldNumber_LastStreamIdReceived = 6, + GtalkLoginResponse_FieldNumber_HeartbeatConfig = 7, + GtalkLoginResponse_FieldNumber_ServerTimestamp = 8, +}; + +@interface GtalkLoginResponse : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkSetting*> *settingArray; +/** The number of items in @c settingArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger settingArray_Count; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkHeartbeatConfig *heartbeatConfig; +/** Test to see if @c heartbeatConfig has been set. */ +@property(nonatomic, readwrite) BOOL hasHeartbeatConfig; + + +@property(nonatomic, readwrite) int64_t serverTimestamp; + +@property(nonatomic, readwrite) BOOL hasServerTimestamp; +@end + +#pragma mark - GtalkBindAccountRequest + +typedef GPB_ENUM(GtalkBindAccountRequest_FieldNumber) { + GtalkBindAccountRequest_FieldNumber_Id_p = 1, + GtalkBindAccountRequest_FieldNumber_Domain = 2, + GtalkBindAccountRequest_FieldNumber_User = 3, + GtalkBindAccountRequest_FieldNumber_Resource = 4, + GtalkBindAccountRequest_FieldNumber_AuthToken = 5, + GtalkBindAccountRequest_FieldNumber_PersistentId = 6, + GtalkBindAccountRequest_FieldNumber_StreamId = 7, + GtalkBindAccountRequest_FieldNumber_LastStreamIdReceived = 8, + GtalkBindAccountRequest_FieldNumber_AccountId = 9, +}; + +@interface GtalkBindAccountRequest : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *domain; +/** Test to see if @c domain has been set. */ +@property(nonatomic, readwrite) BOOL hasDomain; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *resource; +/** Test to see if @c resource has been set. */ +@property(nonatomic, readwrite) BOOL hasResource; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *authToken; +/** Test to see if @c authToken has been set. */ +@property(nonatomic, readwrite) BOOL hasAuthToken; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; +@end + +#pragma mark - GtalkBindAccountResponse + +typedef GPB_ENUM(GtalkBindAccountResponse_FieldNumber) { + GtalkBindAccountResponse_FieldNumber_Id_p = 1, + GtalkBindAccountResponse_FieldNumber_Jid = 2, + GtalkBindAccountResponse_FieldNumber_Error = 3, + GtalkBindAccountResponse_FieldNumber_StreamId = 4, + GtalkBindAccountResponse_FieldNumber_LastStreamIdReceived = 5, +}; + +@interface GtalkBindAccountResponse : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; +@end + +#pragma mark - GtalkStreamErrorStanza + +typedef GPB_ENUM(GtalkStreamErrorStanza_FieldNumber) { + GtalkStreamErrorStanza_FieldNumber_Type = 1, + GtalkStreamErrorStanza_FieldNumber_Text = 2, +}; + +@interface GtalkStreamErrorStanza : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *type; +/** Test to see if @c type has been set. */ +@property(nonatomic, readwrite) BOOL hasType; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *text; +/** Test to see if @c text has been set. */ +@property(nonatomic, readwrite) BOOL hasText; + +@end + +#pragma mark - GtalkClose + +@interface GtalkClose : GPBMessage + +@end + +#pragma mark - GtalkExtension + +typedef GPB_ENUM(GtalkExtension_FieldNumber) { + GtalkExtension_FieldNumber_Id_p = 1, + GtalkExtension_FieldNumber_Data_p = 2, +}; + +@interface GtalkExtension : GPBMessage + + +@property(nonatomic, readwrite) int32_t id_p; + +@property(nonatomic, readwrite) BOOL hasId_p; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *data_p; +/** Test to see if @c data_p has been set. */ +@property(nonatomic, readwrite) BOOL hasData_p; + +@end + +#pragma mark - GtalkMessageStanza + +typedef GPB_ENUM(GtalkMessageStanza_FieldNumber) { + GtalkMessageStanza_FieldNumber_RmqId = 1, + GtalkMessageStanza_FieldNumber_Type = 2, + GtalkMessageStanza_FieldNumber_Id_p = 3, + GtalkMessageStanza_FieldNumber_From = 4, + GtalkMessageStanza_FieldNumber_To = 5, + GtalkMessageStanza_FieldNumber_Subject = 6, + GtalkMessageStanza_FieldNumber_Body = 7, + GtalkMessageStanza_FieldNumber_Thread = 8, + GtalkMessageStanza_FieldNumber_Error = 9, + GtalkMessageStanza_FieldNumber_ExtensionArray = 10, + GtalkMessageStanza_FieldNumber_Nosave = 11, + GtalkMessageStanza_FieldNumber_Timestamp = 12, + GtalkMessageStanza_FieldNumber_PersistentId = 13, + GtalkMessageStanza_FieldNumber_StreamId = 14, + GtalkMessageStanza_FieldNumber_LastStreamIdReceived = 15, + GtalkMessageStanza_FieldNumber_Read = 16, + GtalkMessageStanza_FieldNumber_AccountId = 17, +}; + +@interface GtalkMessageStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite) GtalkMessageStanza_MessageType type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *subject; +/** Test to see if @c subject has been set. */ +@property(nonatomic, readwrite) BOOL hasSubject; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *body; +/** Test to see if @c body has been set. */ +@property(nonatomic, readwrite) BOOL hasBody; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *thread; +/** Test to see if @c thread has been set. */ +@property(nonatomic, readwrite) BOOL hasThread; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkExtension*> *extensionArray; +/** The number of items in @c extensionArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger extensionArray_Count; + + +@property(nonatomic, readwrite) BOOL nosave; + +@property(nonatomic, readwrite) BOOL hasNosave; + +@property(nonatomic, readwrite) int64_t timestamp; + +@property(nonatomic, readwrite) BOOL hasTimestamp; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL read; + +@property(nonatomic, readwrite) BOOL hasRead; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; +@end + +#pragma mark - GtalkPresenceStanza + +typedef GPB_ENUM(GtalkPresenceStanza_FieldNumber) { + GtalkPresenceStanza_FieldNumber_RmqId = 1, + GtalkPresenceStanza_FieldNumber_Type = 2, + GtalkPresenceStanza_FieldNumber_Id_p = 3, + GtalkPresenceStanza_FieldNumber_From = 4, + GtalkPresenceStanza_FieldNumber_To = 5, + GtalkPresenceStanza_FieldNumber_Show = 6, + GtalkPresenceStanza_FieldNumber_Status = 7, + GtalkPresenceStanza_FieldNumber_Priority = 8, + GtalkPresenceStanza_FieldNumber_Error = 9, + GtalkPresenceStanza_FieldNumber_ExtensionArray = 10, + GtalkPresenceStanza_FieldNumber_Client = 11, + GtalkPresenceStanza_FieldNumber_AvatarHash = 12, + GtalkPresenceStanza_FieldNumber_PersistentId = 13, + GtalkPresenceStanza_FieldNumber_StreamId = 14, + GtalkPresenceStanza_FieldNumber_LastStreamIdReceived = 15, + GtalkPresenceStanza_FieldNumber_CapabilitiesFlags = 16, + GtalkPresenceStanza_FieldNumber_AccountId = 17, +}; + +@interface GtalkPresenceStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite) GtalkPresenceStanza_PresenceType type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite) GtalkPresenceStanza_ShowType show; + +@property(nonatomic, readwrite) BOOL hasShow; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *status; +/** Test to see if @c status has been set. */ +@property(nonatomic, readwrite) BOOL hasStatus; + + +@property(nonatomic, readwrite) int32_t priority; + +@property(nonatomic, readwrite) BOOL hasPriority; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkExtension*> *extensionArray; +/** The number of items in @c extensionArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger extensionArray_Count; + + +@property(nonatomic, readwrite) GtalkPresenceStanza_ClientType client; + +@property(nonatomic, readwrite) BOOL hasClient; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *avatarHash; +/** Test to see if @c avatarHash has been set. */ +@property(nonatomic, readwrite) BOOL hasAvatarHash; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int32_t capabilitiesFlags; + +@property(nonatomic, readwrite) BOOL hasCapabilitiesFlags; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; +@end + +#pragma mark - GtalkBatchPresenceStanza + +typedef GPB_ENUM(GtalkBatchPresenceStanza_FieldNumber) { + GtalkBatchPresenceStanza_FieldNumber_Id_p = 1, + GtalkBatchPresenceStanza_FieldNumber_To = 2, + GtalkBatchPresenceStanza_FieldNumber_PresenceArray = 3, + GtalkBatchPresenceStanza_FieldNumber_PersistentId = 4, + GtalkBatchPresenceStanza_FieldNumber_StreamId = 5, + GtalkBatchPresenceStanza_FieldNumber_LastStreamIdReceived = 6, + GtalkBatchPresenceStanza_FieldNumber_AccountId = 7, + GtalkBatchPresenceStanza_FieldNumber_Type = 8, + GtalkBatchPresenceStanza_FieldNumber_Error = 9, +}; + +@interface GtalkBatchPresenceStanza : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkPresenceStanza*> *presenceArray; +/** The number of items in @c presenceArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger presenceArray_Count; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; + +@property(nonatomic, readwrite) GtalkBatchPresenceStanza_Type type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + +@end + +#pragma mark - GtalkIqStanza + +typedef GPB_ENUM(GtalkIqStanza_FieldNumber) { + GtalkIqStanza_FieldNumber_RmqId = 1, + GtalkIqStanza_FieldNumber_Type = 2, + GtalkIqStanza_FieldNumber_Id_p = 3, + GtalkIqStanza_FieldNumber_From = 4, + GtalkIqStanza_FieldNumber_To = 5, + GtalkIqStanza_FieldNumber_Error = 6, + GtalkIqStanza_FieldNumber_Extension = 7, + GtalkIqStanza_FieldNumber_PersistentId = 8, + GtalkIqStanza_FieldNumber_StreamId = 9, + GtalkIqStanza_FieldNumber_LastStreamIdReceived = 10, + GtalkIqStanza_FieldNumber_AccountId = 11, + GtalkIqStanza_FieldNumber_Status = 12, +}; + +@interface GtalkIqStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite) GtalkIqStanza_IqType type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkErrorInfo *error; +/** Test to see if @c error has been set. */ +@property(nonatomic, readwrite) BOOL hasError; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkExtension *extension; +/** Test to see if @c extension has been set. */ +@property(nonatomic, readwrite) BOOL hasExtension; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite) int64_t accountId; + +@property(nonatomic, readwrite) BOOL hasAccountId; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; +@end + +#pragma mark - GtalkAppData + +typedef GPB_ENUM(GtalkAppData_FieldNumber) { + GtalkAppData_FieldNumber_Key = 1, + GtalkAppData_FieldNumber_Value = 2, +}; + +@interface GtalkAppData : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *key; +/** Test to see if @c key has been set. */ +@property(nonatomic, readwrite) BOOL hasKey; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *value; +/** Test to see if @c value has been set. */ +@property(nonatomic, readwrite) BOOL hasValue; + +@end + +#pragma mark - GtalkDataMessageStanza + +typedef GPB_ENUM(GtalkDataMessageStanza_FieldNumber) { + GtalkDataMessageStanza_FieldNumber_RmqId = 1, + GtalkDataMessageStanza_FieldNumber_Id_p = 2, + GtalkDataMessageStanza_FieldNumber_From = 3, + GtalkDataMessageStanza_FieldNumber_To = 4, + GtalkDataMessageStanza_FieldNumber_Category = 5, + GtalkDataMessageStanza_FieldNumber_Token = 6, + GtalkDataMessageStanza_FieldNumber_AppDataArray = 7, + GtalkDataMessageStanza_FieldNumber_FromTrustedServer = 8, + GtalkDataMessageStanza_FieldNumber_PersistentId = 9, + GtalkDataMessageStanza_FieldNumber_StreamId = 10, + GtalkDataMessageStanza_FieldNumber_LastStreamIdReceived = 11, + GtalkDataMessageStanza_FieldNumber_Permission = 12, + GtalkDataMessageStanza_FieldNumber_RegId = 13, + GtalkDataMessageStanza_FieldNumber_PkgSignature = 14, + GtalkDataMessageStanza_FieldNumber_ClientId = 15, + GtalkDataMessageStanza_FieldNumber_DeviceUserId = 16, + GtalkDataMessageStanza_FieldNumber_Ttl = 17, + GtalkDataMessageStanza_FieldNumber_Sent = 18, + GtalkDataMessageStanza_FieldNumber_Queued = 19, + GtalkDataMessageStanza_FieldNumber_Status = 20, + GtalkDataMessageStanza_FieldNumber_RawData = 21, + GtalkDataMessageStanza_FieldNumber_MaxDelay = 22, + GtalkDataMessageStanza_FieldNumber_ActualDelay = 23, + GtalkDataMessageStanza_FieldNumber_ImmediateAck = 24, + GtalkDataMessageStanza_FieldNumber_DeliveryReceiptRequested = 25, + GtalkDataMessageStanza_FieldNumber_ExternalMessageId = 26, + GtalkDataMessageStanza_FieldNumber_Flags = 27, + GtalkDataMessageStanza_FieldNumber_CellTower = 28, + GtalkDataMessageStanza_FieldNumber_Priority = 29, +}; + +@interface GtalkDataMessageStanza : GPBMessage + + +@property(nonatomic, readwrite) int64_t rmqId; + +@property(nonatomic, readwrite) BOOL hasRmqId; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *from; +/** Test to see if @c from has been set. */ +@property(nonatomic, readwrite) BOOL hasFrom; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *to; +/** Test to see if @c to has been set. */ +@property(nonatomic, readwrite) BOOL hasTo; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *category; +/** Test to see if @c category has been set. */ +@property(nonatomic, readwrite) BOOL hasCategory; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *token; +/** Test to see if @c token has been set. */ +@property(nonatomic, readwrite) BOOL hasToken; + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkAppData*> *appDataArray; +/** The number of items in @c appDataArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger appDataArray_Count; + + +@property(nonatomic, readwrite) BOOL fromTrustedServer; + +@property(nonatomic, readwrite) BOOL hasFromTrustedServer; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *persistentId; +/** Test to see if @c persistentId has been set. */ +@property(nonatomic, readwrite) BOOL hasPersistentId; + + +@property(nonatomic, readwrite) int32_t streamId; + +@property(nonatomic, readwrite) BOOL hasStreamId; + +@property(nonatomic, readwrite) int32_t lastStreamIdReceived; + +@property(nonatomic, readwrite) BOOL hasLastStreamIdReceived; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *permission; +/** Test to see if @c permission has been set. */ +@property(nonatomic, readwrite) BOOL hasPermission; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *regId; +/** Test to see if @c regId has been set. */ +@property(nonatomic, readwrite) BOOL hasRegId; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *pkgSignature; +/** Test to see if @c pkgSignature has been set. */ +@property(nonatomic, readwrite) BOOL hasPkgSignature; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *clientId; +/** Test to see if @c clientId has been set. */ +@property(nonatomic, readwrite) BOOL hasClientId; + + +@property(nonatomic, readwrite) int64_t deviceUserId; + +@property(nonatomic, readwrite) BOOL hasDeviceUserId; + +@property(nonatomic, readwrite) int32_t ttl; + +@property(nonatomic, readwrite) BOOL hasTtl; + +@property(nonatomic, readwrite) int64_t sent; + +@property(nonatomic, readwrite) BOOL hasSent; + +@property(nonatomic, readwrite) int32_t queued; + +@property(nonatomic, readwrite) BOOL hasQueued; + +@property(nonatomic, readwrite) int64_t status; + +@property(nonatomic, readwrite) BOOL hasStatus; + +@property(nonatomic, readwrite, copy, null_resettable) NSData *rawData; +/** Test to see if @c rawData has been set. */ +@property(nonatomic, readwrite) BOOL hasRawData; + + +@property(nonatomic, readwrite) int32_t maxDelay; + +@property(nonatomic, readwrite) BOOL hasMaxDelay; + +@property(nonatomic, readwrite) int32_t actualDelay; + +@property(nonatomic, readwrite) BOOL hasActualDelay; + +@property(nonatomic, readwrite) BOOL immediateAck; + +@property(nonatomic, readwrite) BOOL hasImmediateAck; + +@property(nonatomic, readwrite) BOOL deliveryReceiptRequested; + +@property(nonatomic, readwrite) BOOL hasDeliveryReceiptRequested; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *externalMessageId; +/** Test to see if @c externalMessageId has been set. */ +@property(nonatomic, readwrite) BOOL hasExternalMessageId; + + +@property(nonatomic, readwrite) int64_t flags; + +@property(nonatomic, readwrite) BOOL hasFlags; + +@property(nonatomic, readwrite, strong, null_resettable) GtalkCellTower *cellTower DEPRECATED_ATTRIBUTE; +/** Test to see if @c cellTower has been set. */ +@property(nonatomic, readwrite) BOOL hasCellTower DEPRECATED_ATTRIBUTE; + + +@property(nonatomic, readwrite) int32_t priority; + +@property(nonatomic, readwrite) BOOL hasPriority; +@end + +#pragma mark - GtalkTalkMetadata + +typedef GPB_ENUM(GtalkTalkMetadata_FieldNumber) { + GtalkTalkMetadata_FieldNumber_Foreground = 1, +}; + +@interface GtalkTalkMetadata : GPBMessage + + +@property(nonatomic, readwrite) BOOL foreground; + +@property(nonatomic, readwrite) BOOL hasForeground; +@end + +#pragma mark - GtalkCellTower + +typedef GPB_ENUM(GtalkCellTower_FieldNumber) { + GtalkCellTower_FieldNumber_Id_p = 1, + GtalkCellTower_FieldNumber_KnownCongestionStatus = 2, +}; + +DEPRECATED_ATTRIBUTE +@interface GtalkCellTower : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *id_p; +/** Test to see if @c id_p has been set. */ +@property(nonatomic, readwrite) BOOL hasId_p; + + +@property(nonatomic, readwrite) int32_t knownCongestionStatus; + +@property(nonatomic, readwrite) BOOL hasKnownCongestionStatus; +@end + +#pragma mark - GtalkClientEvent + +typedef GPB_ENUM(GtalkClientEvent_FieldNumber) { + GtalkClientEvent_FieldNumber_Type = 1, + GtalkClientEvent_FieldNumber_NumberDiscardedEvents = 100, + GtalkClientEvent_FieldNumber_NetworkType = 200, + GtalkClientEvent_FieldNumber_NetworkPort = 201, + GtalkClientEvent_FieldNumber_TimeConnectionStartedMs = 202, + GtalkClientEvent_FieldNumber_TimeConnectionEndedMs = 203, + GtalkClientEvent_FieldNumber_ErrorCode = 204, + GtalkClientEvent_FieldNumber_TimeConnectionEstablishedMs = 300, + GtalkClientEvent_FieldNumber_McsReconnectAction = 400, +}; + +@interface GtalkClientEvent : GPBMessage + + +@property(nonatomic, readwrite) GtalkClientEvent_Type type; + +@property(nonatomic, readwrite) BOOL hasType; + +@property(nonatomic, readwrite) uint32_t numberDiscardedEvents; + +@property(nonatomic, readwrite) BOOL hasNumberDiscardedEvents; + +@property(nonatomic, readwrite) int32_t networkType; + +@property(nonatomic, readwrite) BOOL hasNetworkType; + +@property(nonatomic, readwrite) int32_t networkPort; + +@property(nonatomic, readwrite) BOOL hasNetworkPort; + +@property(nonatomic, readwrite) uint64_t timeConnectionStartedMs; + +@property(nonatomic, readwrite) BOOL hasTimeConnectionStartedMs; + +@property(nonatomic, readwrite) uint64_t timeConnectionEndedMs; + +@property(nonatomic, readwrite) BOOL hasTimeConnectionEndedMs; + +@property(nonatomic, readwrite) int32_t errorCode; + +@property(nonatomic, readwrite) BOOL hasErrorCode; + +@property(nonatomic, readwrite) uint64_t timeConnectionEstablishedMs; + +@property(nonatomic, readwrite) BOOL hasTimeConnectionEstablishedMs; + +@property(nonatomic, readwrite) GtalkClientEvent_McsReconnectAction mcsReconnectAction; + +@property(nonatomic, readwrite) BOOL hasMcsReconnectAction; +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.m new file mode 100644 index 00000000..06c91346 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkCore.pbobjc.m @@ -0,0 +1,3017 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_core.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h> +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + + #import "GtalkCore.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - GtalkGtalkCoreRoot + +@implementation GtalkGtalkCoreRoot + +// No extensions in the file and no imports, so no need to generate +// +extensionRegistry. + +@end + +#pragma mark - GtalkGtalkCoreRoot_FileDescriptor + +static GPBFileDescriptor *GtalkGtalkCoreRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"mobilegtalk" + objcPrefix:@"Gtalk" + syntax:GPBFileSyntaxProto2]; + } + return descriptor; +} + +#pragma mark - GtalkHeartbeatPing + +@implementation GtalkHeartbeatPing + +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasStatus, status; +@dynamic hasCellTower, cellTower; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatPing__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t intervalMs; + GtalkCellTower *cellTower; + int64_t status; +} GtalkHeartbeatPing__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_StreamId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_LastStreamIdReceived, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_Status, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkHeartbeatPing_FieldNumber_CellTower, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatPing_FieldNumber_IntervalMs, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkHeartbeatPing__storage_, intervalMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatPing class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatPing__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkHeartbeatAck + +@implementation GtalkHeartbeatAck + +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasStatus, status; +@dynamic hasCellTower, cellTower; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatAck__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t intervalMs; + GtalkCellTower *cellTower; + int64_t status; +} GtalkHeartbeatAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_StreamId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_LastStreamIdReceived, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_Status, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkHeartbeatAck_FieldNumber_CellTower, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatAck_FieldNumber_IntervalMs, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkHeartbeatAck__storage_, intervalMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatAck class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkErrorInfo + +@implementation GtalkErrorInfo + +@dynamic hasCode, code; +@dynamic hasMessage, message; +@dynamic hasType, type; +@dynamic hasExtension, extension; + +typedef struct GtalkErrorInfo__storage_ { + uint32_t _has_storage_[1]; + int32_t code; + NSString *message; + NSString *type; + GtalkExtension *extension; +} GtalkErrorInfo__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "code", + .dataTypeSpecific.className = NULL, + .number = GtalkErrorInfo_FieldNumber_Code, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, code), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt32, + }, + { + .name = "message", + .dataTypeSpecific.className = NULL, + .number = GtalkErrorInfo_FieldNumber_Message, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, message), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "type", + .dataTypeSpecific.className = NULL, + .number = GtalkErrorInfo_FieldNumber_Type, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, type), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "extension", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkErrorInfo_FieldNumber_Extension, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkErrorInfo__storage_, extension), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkErrorInfo class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkErrorInfo__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkSetting + +@implementation GtalkSetting + +@dynamic hasName, name; +@dynamic hasValue, value; + +typedef struct GtalkSetting__storage_ { + uint32_t _has_storage_[1]; + NSString *name; + NSString *value; +} GtalkSetting__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GtalkSetting_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkSetting__storage_, name), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "value", + .dataTypeSpecific.className = NULL, + .number = GtalkSetting_FieldNumber_Value, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkSetting__storage_, value), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSetting class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSetting__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkHeartbeatStat + +@implementation GtalkHeartbeatStat + +@dynamic hasIp, ip; +@dynamic hasTimeout, timeout; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatStat__storage_ { + uint32_t _has_storage_[1]; + int32_t intervalMs; + NSString *ip; +} GtalkHeartbeatStat__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "ip", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatStat_FieldNumber_Ip, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkHeartbeatStat__storage_, ip), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "timeout", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatStat_FieldNumber_Timeout, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatStat_FieldNumber_IntervalMs, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatStat__storage_, intervalMs), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatStat class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatStat__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkHeartbeatConfig + +@implementation GtalkHeartbeatConfig + +@dynamic hasUploadStat, uploadStat; +@dynamic hasIp, ip; +@dynamic hasIntervalMs, intervalMs; + +typedef struct GtalkHeartbeatConfig__storage_ { + uint32_t _has_storage_[1]; + int32_t intervalMs; + NSString *ip; +} GtalkHeartbeatConfig__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "uploadStat", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatConfig_FieldNumber_UploadStat, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "ip", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatConfig_FieldNumber_Ip, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkHeartbeatConfig__storage_, ip), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "intervalMs", + .dataTypeSpecific.className = NULL, + .number = GtalkHeartbeatConfig_FieldNumber_IntervalMs, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkHeartbeatConfig__storage_, intervalMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkHeartbeatConfig class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkHeartbeatConfig__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkLoginRequest + +@implementation GtalkLoginRequest + +@dynamic hasId_p, id_p; +@dynamic hasDomain, domain; +@dynamic hasUser, user; +@dynamic hasResource, resource; +@dynamic hasAuthToken, authToken; +@dynamic hasDeviceId, deviceId; +@dynamic hasLastRmqId, lastRmqId; +@dynamic settingArray, settingArray_Count; +@dynamic receivedPersistentIdArray, receivedPersistentIdArray_Count; +@dynamic hasIncludeStreamIds, includeStreamIds; +@dynamic hasHeartbeatStat, heartbeatStat; +@dynamic hasUseRmq2, useRmq2; +@dynamic hasAccountId, accountId; +@dynamic hasAuthService, authService; +@dynamic hasNetworkType, networkType; +@dynamic hasStatus, status; +@dynamic hasTokenVersionInfo, tokenVersionInfo; +@dynamic hasCellTower, cellTower; +@dynamic hasGcmStartTimeMs, gcmStartTimeMs; +@dynamic clientEventArray, clientEventArray_Count; +@dynamic hasOnFallback, onFallback; +@dynamic hasNoPendingUpstream, noPendingUpstream; +@dynamic hasReconnectRequestId, reconnectRequestId; + +typedef struct GtalkLoginRequest__storage_ { + uint32_t _has_storage_[1]; + GtalkLoginRequest_AuthService authService; + int32_t networkType; + int32_t reconnectRequestId; + NSString *id_p; + NSString *domain; + NSString *user; + NSString *resource; + NSString *authToken; + NSString *deviceId; + NSMutableArray *settingArray; + NSMutableArray *receivedPersistentIdArray; + GtalkHeartbeatStat *heartbeatStat; + NSString *tokenVersionInfo; + GtalkCellTower *cellTower; + NSMutableArray *clientEventArray; + int64_t lastRmqId; + int64_t accountId; + int64_t status; + uint64_t gcmStartTimeMs; +} GtalkLoginRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "domain", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Domain, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, domain), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_User, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "resource", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Resource, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, resource), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "authToken", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_AuthToken, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, authToken), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "deviceId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_DeviceId, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, deviceId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "lastRmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_LastRmqId, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, lastRmqId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "settingArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkSetting), + .number = GtalkLoginRequest_FieldNumber_SettingArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, settingArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "receivedPersistentIdArray", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_ReceivedPersistentIdArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, receivedPersistentIdArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + { + .name = "includeStreamIds", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_IncludeStreamIds, + .hasIndex = 7, + .offset = 8, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "heartbeatStat", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkHeartbeatStat), + .number = GtalkLoginRequest_FieldNumber_HeartbeatStat, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, heartbeatStat), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "useRmq2", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_UseRmq2, + .hasIndex = 10, + .offset = 11, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_AccountId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "authService", + .dataTypeSpecific.enumDescFunc = GtalkLoginRequest_AuthService_EnumDescriptor, + .number = GtalkLoginRequest_FieldNumber_AuthService, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, authService), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "networkType", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_NetworkType, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, networkType), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_Status, + .hasIndex = 15, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "tokenVersionInfo", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_TokenVersionInfo, + .hasIndex = 16, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, tokenVersionInfo), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkLoginRequest_FieldNumber_CellTower, + .hasIndex = 17, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "gcmStartTimeMs", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_GcmStartTimeMs, + .hasIndex = 18, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, gcmStartTimeMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "clientEventArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkClientEvent), + .number = GtalkLoginRequest_FieldNumber_ClientEventArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, clientEventArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "onFallback", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_OnFallback, + .hasIndex = 19, + .offset = 20, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "noPendingUpstream", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_NoPendingUpstream, + .hasIndex = 21, + .offset = 22, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "reconnectRequestId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginRequest_FieldNumber_ReconnectRequestId, + .hasIndex = 23, + .offset = (uint32_t)offsetof(GtalkLoginRequest__storage_, reconnectRequestId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkLoginRequest class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkLoginRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkLoginRequest_AuthService + +GPBEnumDescriptor *GtalkLoginRequest_AuthService_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Mail\000AndroidCloudToDeviceMessage\000Android" + "Id\000"; + static const int32_t values[] = { + GtalkLoginRequest_AuthService_Mail, + GtalkLoginRequest_AuthService_AndroidCloudToDeviceMessage, + GtalkLoginRequest_AuthService_AndroidId, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkLoginRequest_AuthService) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkLoginRequest_AuthService_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkLoginRequest_AuthService_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkLoginRequest_AuthService_Mail: + case GtalkLoginRequest_AuthService_AndroidCloudToDeviceMessage: + case GtalkLoginRequest_AuthService_AndroidId: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkLoginResponse + +@implementation GtalkLoginResponse + +@dynamic hasId_p, id_p; +@dynamic hasJid, jid; +@dynamic hasError, error; +@dynamic settingArray, settingArray_Count; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasHeartbeatConfig, heartbeatConfig; +@dynamic hasServerTimestamp, serverTimestamp; + +typedef struct GtalkLoginResponse__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *jid; + GtalkErrorInfo *error; + NSMutableArray *settingArray; + GtalkHeartbeatConfig *heartbeatConfig; + int64_t serverTimestamp; +} GtalkLoginResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_Jid, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, jid), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkLoginResponse_FieldNumber_Error, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "settingArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkSetting), + .number = GtalkLoginResponse_FieldNumber_SettingArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, settingArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_StreamId, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_LastStreamIdReceived, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "heartbeatConfig", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkHeartbeatConfig), + .number = GtalkLoginResponse_FieldNumber_HeartbeatConfig, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, heartbeatConfig), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "serverTimestamp", + .dataTypeSpecific.className = NULL, + .number = GtalkLoginResponse_FieldNumber_ServerTimestamp, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkLoginResponse__storage_, serverTimestamp), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkLoginResponse class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkLoginResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkBindAccountRequest + +@implementation GtalkBindAccountRequest + +@dynamic hasId_p, id_p; +@dynamic hasDomain, domain; +@dynamic hasUser, user; +@dynamic hasResource, resource; +@dynamic hasAuthToken, authToken; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasAccountId, accountId; + +typedef struct GtalkBindAccountRequest__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *domain; + NSString *user; + NSString *resource; + NSString *authToken; + NSString *persistentId; + int64_t accountId; +} GtalkBindAccountRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "domain", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_Domain, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, domain), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_User, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "resource", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_Resource, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, resource), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "authToken", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_AuthToken, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, authToken), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_PersistentId, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_StreamId, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_LastStreamIdReceived, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountRequest_FieldNumber_AccountId, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkBindAccountRequest__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkBindAccountRequest class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkBindAccountRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkBindAccountResponse + +@implementation GtalkBindAccountResponse + +@dynamic hasId_p, id_p; +@dynamic hasJid, jid; +@dynamic hasError, error; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; + +typedef struct GtalkBindAccountResponse__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *jid; + GtalkErrorInfo *error; +} GtalkBindAccountResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_Jid, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, jid), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkBindAccountResponse_FieldNumber_Error, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_StreamId, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkBindAccountResponse_FieldNumber_LastStreamIdReceived, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkBindAccountResponse__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkBindAccountResponse class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkBindAccountResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkStreamErrorStanza + +@implementation GtalkStreamErrorStanza + +@dynamic hasType, type; +@dynamic hasText, text; + +typedef struct GtalkStreamErrorStanza__storage_ { + uint32_t _has_storage_[1]; + NSString *type; + NSString *text; +} GtalkStreamErrorStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "type", + .dataTypeSpecific.className = NULL, + .number = GtalkStreamErrorStanza_FieldNumber_Type, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkStreamErrorStanza__storage_, type), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "text", + .dataTypeSpecific.className = NULL, + .number = GtalkStreamErrorStanza_FieldNumber_Text, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkStreamErrorStanza__storage_, text), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkStreamErrorStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkStreamErrorStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkClose + +@implementation GtalkClose + + +typedef struct GtalkClose__storage_ { + uint32_t _has_storage_[1]; +} GtalkClose__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkClose class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:NULL + fieldCount:0 + storageSize:sizeof(GtalkClose__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkExtension + +@implementation GtalkExtension + +@dynamic hasId_p, id_p; +@dynamic hasData_p, data_p; + +typedef struct GtalkExtension__storage_ { + uint32_t _has_storage_[1]; + int32_t id_p; + NSString *data_p; +} GtalkExtension__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkExtension_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkExtension__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt32, + }, + { + .name = "data_p", + .dataTypeSpecific.className = NULL, + .number = GtalkExtension_FieldNumber_Data_p, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkExtension__storage_, data_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkExtension class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkExtension__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkMessageStanza + +@implementation GtalkMessageStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasType, type; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasSubject, subject; +@dynamic hasBody, body; +@dynamic hasThread, thread; +@dynamic hasError, error; +@dynamic extensionArray, extensionArray_Count; +@dynamic hasNosave, nosave; +@dynamic hasTimestamp, timestamp; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasRead, read; +@dynamic hasAccountId, accountId; + +typedef struct GtalkMessageStanza__storage_ { + uint32_t _has_storage_[1]; + GtalkMessageStanza_MessageType type; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *from; + NSString *to; + NSString *subject; + NSString *body; + NSString *thread; + GtalkErrorInfo *error; + NSMutableArray *extensionArray; + NSString *persistentId; + int64_t rmqId; + int64_t timestamp; + int64_t accountId; +} GtalkMessageStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, rmqId), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkMessageStanza_MessageType_EnumDescriptor, + .number = GtalkMessageStanza_FieldNumber_Type, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Id_p, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_From, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, from), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_To, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "subject", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Subject, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, subject), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "body", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Body, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, body), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "thread", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Thread, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, thread), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkMessageStanza_FieldNumber_Error, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "extensionArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkMessageStanza_FieldNumber_ExtensionArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, extensionArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "nosave", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Nosave, + .hasIndex = 9, + .offset = 10, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "timestamp", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Timestamp, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, timestamp), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_PersistentId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_StreamId, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "read", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_Read, + .hasIndex = 15, + .offset = 16, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkMessageStanza_FieldNumber_AccountId, + .hasIndex = 17, + .offset = (uint32_t)offsetof(GtalkMessageStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkMessageStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkMessageStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; +#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + static const char *extraTextFormatInfo = + "\001\001\005\000"; + [localDescriptor setupExtraTextInfo:extraTextFormatInfo]; +#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkMessageStanza_MessageType + +GPBEnumDescriptor *GtalkMessageStanza_MessageType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Normal\000Chat\000Groupchat\000Headline\000Error\000"; + static const int32_t values[] = { + GtalkMessageStanza_MessageType_Normal, + GtalkMessageStanza_MessageType_Chat, + GtalkMessageStanza_MessageType_Groupchat, + GtalkMessageStanza_MessageType_Headline, + GtalkMessageStanza_MessageType_Error, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkMessageStanza_MessageType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkMessageStanza_MessageType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkMessageStanza_MessageType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkMessageStanza_MessageType_Normal: + case GtalkMessageStanza_MessageType_Chat: + case GtalkMessageStanza_MessageType_Groupchat: + case GtalkMessageStanza_MessageType_Headline: + case GtalkMessageStanza_MessageType_Error: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkPresenceStanza + +@implementation GtalkPresenceStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasType, type; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasShow, show; +@dynamic hasStatus, status; +@dynamic hasPriority, priority; +@dynamic hasError, error; +@dynamic extensionArray, extensionArray_Count; +@dynamic hasClient, client; +@dynamic hasAvatarHash, avatarHash; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasCapabilitiesFlags, capabilitiesFlags; +@dynamic hasAccountId, accountId; + +typedef struct GtalkPresenceStanza__storage_ { + uint32_t _has_storage_[1]; + GtalkPresenceStanza_PresenceType type; + GtalkPresenceStanza_ShowType show; + int32_t priority; + GtalkPresenceStanza_ClientType client; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t capabilitiesFlags; + NSString *id_p; + NSString *from; + NSString *to; + NSString *status; + GtalkErrorInfo *error; + NSMutableArray *extensionArray; + NSString *avatarHash; + NSString *persistentId; + int64_t rmqId; + int64_t accountId; +} GtalkPresenceStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, rmqId), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkPresenceStanza_PresenceType_EnumDescriptor, + .number = GtalkPresenceStanza_FieldNumber_Type, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_Id_p, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_From, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, from), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_To, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "show", + .dataTypeSpecific.enumDescFunc = GtalkPresenceStanza_ShowType_EnumDescriptor, + .number = GtalkPresenceStanza_FieldNumber_Show, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, show), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_Status, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "priority", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_Priority, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, priority), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkPresenceStanza_FieldNumber_Error, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "extensionArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkPresenceStanza_FieldNumber_ExtensionArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, extensionArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "client", + .dataTypeSpecific.enumDescFunc = GtalkPresenceStanza_ClientType_EnumDescriptor, + .number = GtalkPresenceStanza_FieldNumber_Client, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, client), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "avatarHash", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_AvatarHash, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, avatarHash), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_PersistentId, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_StreamId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "capabilitiesFlags", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_CapabilitiesFlags, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, capabilitiesFlags), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkPresenceStanza_FieldNumber_AccountId, + .hasIndex = 15, + .offset = (uint32_t)offsetof(GtalkPresenceStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkPresenceStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkPresenceStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; +#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + static const char *extraTextFormatInfo = + "\001\001\005\000"; + [localDescriptor setupExtraTextInfo:extraTextFormatInfo]; +#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkPresenceStanza_PresenceType + +GPBEnumDescriptor *GtalkPresenceStanza_PresenceType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Unavailable\000Subscribe\000Subscribed\000Unsubsc" + "ribe\000Unsubscribed\000Probe\000Error\000"; + static const int32_t values[] = { + GtalkPresenceStanza_PresenceType_Unavailable, + GtalkPresenceStanza_PresenceType_Subscribe, + GtalkPresenceStanza_PresenceType_Subscribed, + GtalkPresenceStanza_PresenceType_Unsubscribe, + GtalkPresenceStanza_PresenceType_Unsubscribed, + GtalkPresenceStanza_PresenceType_Probe, + GtalkPresenceStanza_PresenceType_Error, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_PresenceType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_PresenceType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_PresenceType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_PresenceType_Unavailable: + case GtalkPresenceStanza_PresenceType_Subscribe: + case GtalkPresenceStanza_PresenceType_Subscribed: + case GtalkPresenceStanza_PresenceType_Unsubscribe: + case GtalkPresenceStanza_PresenceType_Unsubscribed: + case GtalkPresenceStanza_PresenceType_Probe: + case GtalkPresenceStanza_PresenceType_Error: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkPresenceStanza_ShowType + +GPBEnumDescriptor *GtalkPresenceStanza_ShowType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Away\000Chat\000Dnd\000Xa\000"; + static const int32_t values[] = { + GtalkPresenceStanza_ShowType_Away, + GtalkPresenceStanza_ShowType_Chat, + GtalkPresenceStanza_ShowType_Dnd, + GtalkPresenceStanza_ShowType_Xa, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_ShowType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_ShowType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_ShowType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_ShowType_Away: + case GtalkPresenceStanza_ShowType_Chat: + case GtalkPresenceStanza_ShowType_Dnd: + case GtalkPresenceStanza_ShowType_Xa: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkPresenceStanza_ClientType + +GPBEnumDescriptor *GtalkPresenceStanza_ClientType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Mobile\000Android\000"; + static const int32_t values[] = { + GtalkPresenceStanza_ClientType_Mobile, + GtalkPresenceStanza_ClientType_Android, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_ClientType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_ClientType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_ClientType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_ClientType_Mobile: + case GtalkPresenceStanza_ClientType_Android: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkPresenceStanza_CapabilitiesFlags + +GPBEnumDescriptor *GtalkPresenceStanza_CapabilitiesFlags_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "HasVoiceV1\000HasVideoV1\000HasCameraV1\000HasPmu" + "cV1\000"; + static const int32_t values[] = { + GtalkPresenceStanza_CapabilitiesFlags_HasVoiceV1, + GtalkPresenceStanza_CapabilitiesFlags_HasVideoV1, + GtalkPresenceStanza_CapabilitiesFlags_HasCameraV1, + GtalkPresenceStanza_CapabilitiesFlags_HasPmucV1, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPresenceStanza_CapabilitiesFlags) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPresenceStanza_CapabilitiesFlags_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPresenceStanza_CapabilitiesFlags_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPresenceStanza_CapabilitiesFlags_HasVoiceV1: + case GtalkPresenceStanza_CapabilitiesFlags_HasVideoV1: + case GtalkPresenceStanza_CapabilitiesFlags_HasCameraV1: + case GtalkPresenceStanza_CapabilitiesFlags_HasPmucV1: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkBatchPresenceStanza + +@implementation GtalkBatchPresenceStanza + +@dynamic hasId_p, id_p; +@dynamic hasTo, to; +@dynamic presenceArray, presenceArray_Count; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasAccountId, accountId; +@dynamic hasType, type; +@dynamic hasError, error; + +typedef struct GtalkBatchPresenceStanza__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + GtalkBatchPresenceStanza_Type type; + NSString *id_p; + NSString *to; + NSMutableArray *presenceArray; + NSString *persistentId; + GtalkErrorInfo *error; + int64_t accountId; +} GtalkBatchPresenceStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_To, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "presenceArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkPresenceStanza), + .number = GtalkBatchPresenceStanza_FieldNumber_PresenceArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, presenceArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_PersistentId, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_StreamId, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkBatchPresenceStanza_FieldNumber_AccountId, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkBatchPresenceStanza_Type_EnumDescriptor, + .number = GtalkBatchPresenceStanza_FieldNumber_Type, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkBatchPresenceStanza_FieldNumber_Error, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkBatchPresenceStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkBatchPresenceStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkBatchPresenceStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkBatchPresenceStanza_Type + +GPBEnumDescriptor *GtalkBatchPresenceStanza_Type_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Get\000Set\000"; + static const int32_t values[] = { + GtalkBatchPresenceStanza_Type_Get, + GtalkBatchPresenceStanza_Type_Set, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkBatchPresenceStanza_Type) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkBatchPresenceStanza_Type_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkBatchPresenceStanza_Type_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkBatchPresenceStanza_Type_Get: + case GtalkBatchPresenceStanza_Type_Set: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkIqStanza + +@implementation GtalkIqStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasType, type; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasError, error; +@dynamic hasExtension, extension; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasAccountId, accountId; +@dynamic hasStatus, status; + +typedef struct GtalkIqStanza__storage_ { + uint32_t _has_storage_[1]; + GtalkIqStanza_IqType type; + int32_t streamId; + int32_t lastStreamIdReceived; + NSString *id_p; + NSString *from; + NSString *to; + GtalkErrorInfo *error; + GtalkExtension *extension; + NSString *persistentId; + int64_t rmqId; + int64_t accountId; + int64_t status; +} GtalkIqStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, rmqId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkIqStanza_IqType_EnumDescriptor, + .number = GtalkIqStanza_FieldNumber_Type, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldRequired | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_Id_p, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_From, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, from), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_To, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "error", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkErrorInfo), + .number = GtalkIqStanza_FieldNumber_Error, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, error), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "extension", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkExtension), + .number = GtalkIqStanza_FieldNumber_Extension, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, extension), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_PersistentId, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_StreamId, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "accountId", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_AccountId, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, accountId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkIqStanza_FieldNumber_Status, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkIqStanza__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkIqStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkIqStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkIqStanza_IqType + +GPBEnumDescriptor *GtalkIqStanza_IqType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Get\000Set\000Result\000Error\000"; + static const int32_t values[] = { + GtalkIqStanza_IqType_Get, + GtalkIqStanza_IqType_Set, + GtalkIqStanza_IqType_Result, + GtalkIqStanza_IqType_Error, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkIqStanza_IqType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkIqStanza_IqType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkIqStanza_IqType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkIqStanza_IqType_Get: + case GtalkIqStanza_IqType_Set: + case GtalkIqStanza_IqType_Result: + case GtalkIqStanza_IqType_Error: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkAppData + +@implementation GtalkAppData + +@dynamic hasKey, key; +@dynamic hasValue, value; + +typedef struct GtalkAppData__storage_ { + uint32_t _has_storage_[1]; + NSString *key; + NSString *value; +} GtalkAppData__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "key", + .dataTypeSpecific.className = NULL, + .number = GtalkAppData_FieldNumber_Key, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkAppData__storage_, key), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "value", + .dataTypeSpecific.className = NULL, + .number = GtalkAppData_FieldNumber_Value, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkAppData__storage_, value), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkAppData class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkAppData__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkDataMessageStanza + +@implementation GtalkDataMessageStanza + +@dynamic hasRmqId, rmqId; +@dynamic hasId_p, id_p; +@dynamic hasFrom, from; +@dynamic hasTo, to; +@dynamic hasCategory, category; +@dynamic hasToken, token; +@dynamic appDataArray, appDataArray_Count; +@dynamic hasFromTrustedServer, fromTrustedServer; +@dynamic hasPersistentId, persistentId; +@dynamic hasStreamId, streamId; +@dynamic hasLastStreamIdReceived, lastStreamIdReceived; +@dynamic hasPermission, permission; +@dynamic hasRegId, regId; +@dynamic hasPkgSignature, pkgSignature; +@dynamic hasClientId, clientId; +@dynamic hasDeviceUserId, deviceUserId; +@dynamic hasTtl, ttl; +@dynamic hasSent, sent; +@dynamic hasQueued, queued; +@dynamic hasStatus, status; +@dynamic hasRawData, rawData; +@dynamic hasMaxDelay, maxDelay; +@dynamic hasActualDelay, actualDelay; +@dynamic hasImmediateAck, immediateAck; +@dynamic hasDeliveryReceiptRequested, deliveryReceiptRequested; +@dynamic hasExternalMessageId, externalMessageId; +@dynamic hasFlags, flags; +@dynamic hasCellTower, cellTower; +@dynamic hasPriority, priority; + +typedef struct GtalkDataMessageStanza__storage_ { + uint32_t _has_storage_[1]; + int32_t streamId; + int32_t lastStreamIdReceived; + int32_t ttl; + int32_t queued; + int32_t maxDelay; + int32_t actualDelay; + int32_t priority; + NSString *id_p; + NSString *from; + NSString *to; + NSString *category; + NSString *token; + NSMutableArray *appDataArray; + NSString *persistentId; + NSString *permission; + NSString *regId; + NSString *pkgSignature; + NSString *clientId; + NSData *rawData; + NSString *externalMessageId; + GtalkCellTower *cellTower; + int64_t rmqId; + int64_t deviceUserId; + int64_t sent; + int64_t status; + int64_t flags; +} GtalkDataMessageStanza__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rmqId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_RmqId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, rmqId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Id_p, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "from", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_From, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, from), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "to", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_To, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, to), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "category", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Category, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, category), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "token", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Token, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, token), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "appDataArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkAppData), + .number = GtalkDataMessageStanza_FieldNumber_AppDataArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, appDataArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "fromTrustedServer", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_FromTrustedServer, + .hasIndex = 6, + .offset = 7, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "persistentId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_PersistentId, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, persistentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_StreamId, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamIdReceived", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_LastStreamIdReceived, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, lastStreamIdReceived), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "permission", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Permission, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, permission), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "regId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_RegId, + .hasIndex = 12, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, regId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "pkgSignature", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_PkgSignature, + .hasIndex = 13, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, pkgSignature), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "clientId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ClientId, + .hasIndex = 14, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, clientId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "deviceUserId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_DeviceUserId, + .hasIndex = 15, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, deviceUserId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "ttl", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Ttl, + .hasIndex = 16, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, ttl), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "sent", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Sent, + .hasIndex = 17, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, sent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "queued", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Queued, + .hasIndex = 18, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, queued), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Status, + .hasIndex = 19, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "rawData", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_RawData, + .hasIndex = 20, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, rawData), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "maxDelay", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_MaxDelay, + .hasIndex = 21, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, maxDelay), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "actualDelay", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ActualDelay, + .hasIndex = 22, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, actualDelay), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "immediateAck", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ImmediateAck, + .hasIndex = 23, + .offset = 24, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "deliveryReceiptRequested", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_DeliveryReceiptRequested, + .hasIndex = 25, + .offset = 26, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "externalMessageId", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_ExternalMessageId, + .hasIndex = 27, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, externalMessageId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "flags", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Flags, + .hasIndex = 28, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, flags), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "cellTower", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkCellTower), + .number = GtalkDataMessageStanza_FieldNumber_CellTower, + .hasIndex = 29, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, cellTower), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "priority", + .dataTypeSpecific.className = NULL, + .number = GtalkDataMessageStanza_FieldNumber_Priority, + .hasIndex = 30, + .offset = (uint32_t)offsetof(GtalkDataMessageStanza__storage_, priority), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkDataMessageStanza class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkDataMessageStanza__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkTalkMetadata + +@implementation GtalkTalkMetadata + +@dynamic hasForeground, foreground; + +typedef struct GtalkTalkMetadata__storage_ { + uint32_t _has_storage_[1]; +} GtalkTalkMetadata__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "foreground", + .dataTypeSpecific.className = NULL, + .number = GtalkTalkMetadata_FieldNumber_Foreground, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkTalkMetadata class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkTalkMetadata__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkCellTower + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" + +@implementation GtalkCellTower + +@dynamic hasId_p, id_p; +@dynamic hasKnownCongestionStatus, knownCongestionStatus; + +typedef struct GtalkCellTower__storage_ { + uint32_t _has_storage_[1]; + int32_t knownCongestionStatus; + NSString *id_p; +} GtalkCellTower__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkCellTower_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkCellTower__storage_, id_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "knownCongestionStatus", + .dataTypeSpecific.className = NULL, + .number = GtalkCellTower_FieldNumber_KnownCongestionStatus, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkCellTower__storage_, knownCongestionStatus), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkCellTower class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkCellTower__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma clang diagnostic pop + +#pragma mark - GtalkClientEvent + +@implementation GtalkClientEvent + +@dynamic hasType, type; +@dynamic hasNumberDiscardedEvents, numberDiscardedEvents; +@dynamic hasNetworkType, networkType; +@dynamic hasNetworkPort, networkPort; +@dynamic hasTimeConnectionStartedMs, timeConnectionStartedMs; +@dynamic hasTimeConnectionEndedMs, timeConnectionEndedMs; +@dynamic hasErrorCode, errorCode; +@dynamic hasTimeConnectionEstablishedMs, timeConnectionEstablishedMs; +@dynamic hasMcsReconnectAction, mcsReconnectAction; + +typedef struct GtalkClientEvent__storage_ { + uint32_t _has_storage_[1]; + GtalkClientEvent_Type type; + uint32_t numberDiscardedEvents; + int32_t networkType; + int32_t networkPort; + int32_t errorCode; + GtalkClientEvent_McsReconnectAction mcsReconnectAction; + uint64_t timeConnectionStartedMs; + uint64_t timeConnectionEndedMs; + uint64_t timeConnectionEstablishedMs; +} GtalkClientEvent__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "type", + .dataTypeSpecific.enumDescFunc = GtalkClientEvent_Type_EnumDescriptor, + .number = GtalkClientEvent_FieldNumber_Type, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, type), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "numberDiscardedEvents", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_NumberDiscardedEvents, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, numberDiscardedEvents), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt32, + }, + { + .name = "networkType", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_NetworkType, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, networkType), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "networkPort", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_NetworkPort, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, networkPort), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "timeConnectionStartedMs", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_TimeConnectionStartedMs, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, timeConnectionStartedMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "timeConnectionEndedMs", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_TimeConnectionEndedMs, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, timeConnectionEndedMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "errorCode", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_ErrorCode, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, errorCode), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "timeConnectionEstablishedMs", + .dataTypeSpecific.className = NULL, + .number = GtalkClientEvent_FieldNumber_TimeConnectionEstablishedMs, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, timeConnectionEstablishedMs), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeUInt64, + }, + { + .name = "mcsReconnectAction", + .dataTypeSpecific.enumDescFunc = GtalkClientEvent_McsReconnectAction_EnumDescriptor, + .number = GtalkClientEvent_FieldNumber_McsReconnectAction, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkClientEvent__storage_, mcsReconnectAction), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkClientEvent class] + rootClass:[GtalkGtalkCoreRoot class] + file:GtalkGtalkCoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkClientEvent__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkClientEvent_Type + +GPBEnumDescriptor *GtalkClientEvent_Type_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Unknown\000DiscardedEvents\000FailedConnection" + "\000SuccessfulConnection\000McsReconnectReques" + "t\000FailedSocketCreationMcsReconnect\000McsRe" + "connectLimited\000"; + static const int32_t values[] = { + GtalkClientEvent_Type_Unknown, + GtalkClientEvent_Type_DiscardedEvents, + GtalkClientEvent_Type_FailedConnection, + GtalkClientEvent_Type_SuccessfulConnection, + GtalkClientEvent_Type_McsReconnectRequest, + GtalkClientEvent_Type_FailedSocketCreationMcsReconnect, + GtalkClientEvent_Type_McsReconnectLimited, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkClientEvent_Type) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkClientEvent_Type_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkClientEvent_Type_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkClientEvent_Type_Unknown: + case GtalkClientEvent_Type_DiscardedEvents: + case GtalkClientEvent_Type_FailedConnection: + case GtalkClientEvent_Type_SuccessfulConnection: + case GtalkClientEvent_Type_McsReconnectRequest: + case GtalkClientEvent_Type_FailedSocketCreationMcsReconnect: + case GtalkClientEvent_Type_McsReconnectLimited: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkClientEvent_McsReconnectAction + +GPBEnumDescriptor *GtalkClientEvent_McsReconnectAction_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "None\000NotConnected\000TooSoon\000"; + static const int32_t values[] = { + GtalkClientEvent_McsReconnectAction_None, + GtalkClientEvent_McsReconnectAction_NotConnected, + GtalkClientEvent_McsReconnectAction_TooSoon, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkClientEvent_McsReconnectAction) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkClientEvent_McsReconnectAction_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkClientEvent_McsReconnectAction_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkClientEvent_McsReconnectAction_None: + case GtalkClientEvent_McsReconnectAction_NotConnected: + case GtalkClientEvent_McsReconnectAction_TooSoon: + return YES; + default: + return NO; + } +} + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.h new file mode 100644 index 00000000..f461884a --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.h @@ -0,0 +1,617 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_extensions.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import <Protobuf/GPBProtocolBuffers.h> +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GtalkOtrItem; +@class GtalkPhoto; +@class GtalkRosterItem; +@class GtalkSharedStatus_StatusList; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GtalkRosterItem_SubscriptionType + +typedef GPB_ENUM(GtalkRosterItem_SubscriptionType) { + GtalkRosterItem_SubscriptionType_None = 0, + GtalkRosterItem_SubscriptionType_To = 1, + GtalkRosterItem_SubscriptionType_From = 2, + GtalkRosterItem_SubscriptionType_Both = 3, + GtalkRosterItem_SubscriptionType_Remove = 4, +}; + +GPBEnumDescriptor *GtalkRosterItem_SubscriptionType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkRosterItem_SubscriptionType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkRosterItem_AskType + +typedef GPB_ENUM(GtalkRosterItem_AskType) { + GtalkRosterItem_AskType_Subscribe = 0, +}; + +GPBEnumDescriptor *GtalkRosterItem_AskType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkRosterItem_AskType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkRosterItem_DisplayType + +typedef GPB_ENUM(GtalkRosterItem_DisplayType) { + GtalkRosterItem_DisplayType_Blocked = 0, + GtalkRosterItem_DisplayType_Hidden = 1, + GtalkRosterItem_DisplayType_Pinned = 2, +}; + +GPBEnumDescriptor *GtalkRosterItem_DisplayType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkRosterItem_DisplayType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkSharedStatus_ShowType + +typedef GPB_ENUM(GtalkSharedStatus_ShowType) { + GtalkSharedStatus_ShowType_Default = 0, + GtalkSharedStatus_ShowType_Dnd = 1, +}; + +GPBEnumDescriptor *GtalkSharedStatus_ShowType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkSharedStatus_ShowType_IsValidValue(int32_t value); + +#pragma mark - Enum GtalkPostAuthBatchQuery_CapabilitiesExtFlags + +typedef GPB_ENUM(GtalkPostAuthBatchQuery_CapabilitiesExtFlags) { + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVoiceV1 = 1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVideoV1 = 2, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasCameraV1 = 4, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasPmucV1 = 8, +}; + +GPBEnumDescriptor *GtalkPostAuthBatchQuery_CapabilitiesExtFlags_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GtalkPostAuthBatchQuery_CapabilitiesExtFlags_IsValidValue(int32_t value); + +#pragma mark - GtalkGtalkExtensionsRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GtalkGtalkExtensionsRoot : GPBRootObject +@end + +#pragma mark - GtalkRosterQuery + +typedef GPB_ENUM(GtalkRosterQuery_FieldNumber) { + GtalkRosterQuery_FieldNumber_Etag = 1, + GtalkRosterQuery_FieldNumber_NotModified = 2, + GtalkRosterQuery_FieldNumber_ItemArray = 3, + GtalkRosterQuery_FieldNumber_AvatarWidth = 4, + GtalkRosterQuery_FieldNumber_AvatarHeight = 5, +}; + +@interface GtalkRosterQuery : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *etag; +/** Test to see if @c etag has been set. */ +@property(nonatomic, readwrite) BOOL hasEtag; + + +@property(nonatomic, readwrite) BOOL notModified; + +@property(nonatomic, readwrite) BOOL hasNotModified; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkRosterItem*> *itemArray; +/** The number of items in @c itemArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger itemArray_Count; + + +@property(nonatomic, readwrite) int32_t avatarWidth; + +@property(nonatomic, readwrite) BOOL hasAvatarWidth; + +@property(nonatomic, readwrite) int32_t avatarHeight; + +@property(nonatomic, readwrite) BOOL hasAvatarHeight; +@end + +#pragma mark - GtalkRosterItem + +typedef GPB_ENUM(GtalkRosterItem_FieldNumber) { + GtalkRosterItem_FieldNumber_Jid = 1, + GtalkRosterItem_FieldNumber_Name = 2, + GtalkRosterItem_FieldNumber_Subscription = 3, + GtalkRosterItem_FieldNumber_Ask = 4, + GtalkRosterItem_FieldNumber_GroupArray = 5, + GtalkRosterItem_FieldNumber_QuickContact = 6, + GtalkRosterItem_FieldNumber_Display = 7, + GtalkRosterItem_FieldNumber_Rejected = 8, +}; + +@interface GtalkRosterItem : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; +/** Test to see if @c name has been set. */ +@property(nonatomic, readwrite) BOOL hasName; + + +@property(nonatomic, readwrite) GtalkRosterItem_SubscriptionType subscription; + +@property(nonatomic, readwrite) BOOL hasSubscription; + +@property(nonatomic, readwrite) GtalkRosterItem_AskType ask; + +@property(nonatomic, readwrite) BOOL hasAsk; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *groupArray; +/** The number of items in @c groupArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger groupArray_Count; + + +@property(nonatomic, readwrite) BOOL quickContact; + +@property(nonatomic, readwrite) BOOL hasQuickContact; + +@property(nonatomic, readwrite) GtalkRosterItem_DisplayType display; + +@property(nonatomic, readwrite) BOOL hasDisplay; + +@property(nonatomic, readwrite) BOOL rejected; + +@property(nonatomic, readwrite) BOOL hasRejected; +@end + +#pragma mark - GtalkRmqLastId + +typedef GPB_ENUM(GtalkRmqLastId_FieldNumber) { + GtalkRmqLastId_FieldNumber_Id_p = 1, +}; + +@interface GtalkRmqLastId : GPBMessage + + +@property(nonatomic, readwrite) int64_t id_p; + +@property(nonatomic, readwrite) BOOL hasId_p; +@end + +#pragma mark - GtalkRmqAck + +typedef GPB_ENUM(GtalkRmqAck_FieldNumber) { + GtalkRmqAck_FieldNumber_Id_p = 1, +}; + +@interface GtalkRmqAck : GPBMessage + + +@property(nonatomic, readwrite) int64_t id_p; + +@property(nonatomic, readwrite) BOOL hasId_p; +@end + +#pragma mark - GtalkVCard + +typedef GPB_ENUM(GtalkVCard_FieldNumber) { + GtalkVCard_FieldNumber_Version = 1, + GtalkVCard_FieldNumber_FullName = 2, + GtalkVCard_FieldNumber_Photo = 3, + GtalkVCard_FieldNumber_AvatarHash = 4, + GtalkVCard_FieldNumber_Modified = 5, +}; + +@interface GtalkVCard : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *version; +/** Test to see if @c version has been set. */ +@property(nonatomic, readwrite) BOOL hasVersion; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *fullName; +/** Test to see if @c fullName has been set. */ +@property(nonatomic, readwrite) BOOL hasFullName; + + +@property(nonatomic, readwrite, strong, null_resettable) GtalkPhoto *photo; +/** Test to see if @c photo has been set. */ +@property(nonatomic, readwrite) BOOL hasPhoto; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *avatarHash; +/** Test to see if @c avatarHash has been set. */ +@property(nonatomic, readwrite) BOOL hasAvatarHash; + + +@property(nonatomic, readwrite) BOOL modified; + +@property(nonatomic, readwrite) BOOL hasModified; +@end + +#pragma mark - GtalkPhoto + +typedef GPB_ENUM(GtalkPhoto_FieldNumber) { + GtalkPhoto_FieldNumber_Type = 1, + GtalkPhoto_FieldNumber_Data_p = 2, +}; + +@interface GtalkPhoto : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *type; +/** Test to see if @c type has been set. */ +@property(nonatomic, readwrite) BOOL hasType; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *data_p; +/** Test to see if @c data_p has been set. */ +@property(nonatomic, readwrite) BOOL hasData_p; + +@end + +#pragma mark - GtalkChatRead + +typedef GPB_ENUM(GtalkChatRead_FieldNumber) { + GtalkChatRead_FieldNumber_User = 1, +}; + +@interface GtalkChatRead : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + +@end + +#pragma mark - GtalkChatClosed + +typedef GPB_ENUM(GtalkChatClosed_FieldNumber) { + GtalkChatClosed_FieldNumber_User = 1, +}; + +@interface GtalkChatClosed : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *user; +/** Test to see if @c user has been set. */ +@property(nonatomic, readwrite) BOOL hasUser; + +@end + +#pragma mark - GtalkCapabilities + +typedef GPB_ENUM(GtalkCapabilities_FieldNumber) { + GtalkCapabilities_FieldNumber_Node = 1, + GtalkCapabilities_FieldNumber_Ver = 2, + GtalkCapabilities_FieldNumber_Ext = 3, + GtalkCapabilities_FieldNumber_Hash_p = 4, +}; + +@interface GtalkCapabilities : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *node; +/** Test to see if @c node has been set. */ +@property(nonatomic, readwrite) BOOL hasNode; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ver; +/** Test to see if @c ver has been set. */ +@property(nonatomic, readwrite) BOOL hasVer; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *ext; +/** Test to see if @c ext has been set. */ +@property(nonatomic, readwrite) BOOL hasExt; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *hash_p; +/** Test to see if @c hash_p has been set. */ +@property(nonatomic, readwrite) BOOL hasHash_p; + +@end + +#pragma mark - GtalkSharedStatus + +typedef GPB_ENUM(GtalkSharedStatus_FieldNumber) { + GtalkSharedStatus_FieldNumber_StatusMax = 1, + GtalkSharedStatus_FieldNumber_StatusListMax = 2, + GtalkSharedStatus_FieldNumber_StatusListContentsMax = 3, + GtalkSharedStatus_FieldNumber_Status = 4, + GtalkSharedStatus_FieldNumber_Show = 5, + GtalkSharedStatus_FieldNumber_StatusListArray = 6, + GtalkSharedStatus_FieldNumber_Invisible = 9, + GtalkSharedStatus_FieldNumber_StatusMinVersion = 10, +}; + +@interface GtalkSharedStatus : GPBMessage + + +@property(nonatomic, readwrite) int32_t statusMax; + +@property(nonatomic, readwrite) BOOL hasStatusMax; + +@property(nonatomic, readwrite) int32_t statusListMax; + +@property(nonatomic, readwrite) BOOL hasStatusListMax; + +@property(nonatomic, readwrite) int32_t statusListContentsMax; + +@property(nonatomic, readwrite) BOOL hasStatusListContentsMax; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *status; +/** Test to see if @c status has been set. */ +@property(nonatomic, readwrite) BOOL hasStatus; + + +@property(nonatomic, readwrite) GtalkSharedStatus_ShowType show; + +@property(nonatomic, readwrite) BOOL hasShow; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkSharedStatus_StatusList*> *statusListArray; +/** The number of items in @c statusListArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger statusListArray_Count; + + +@property(nonatomic, readwrite) BOOL invisible; + +@property(nonatomic, readwrite) BOOL hasInvisible; + +@property(nonatomic, readwrite) int32_t statusMinVersion; + +@property(nonatomic, readwrite) BOOL hasStatusMinVersion; +@end + +#pragma mark - GtalkSharedStatus_StatusList + +typedef GPB_ENUM(GtalkSharedStatus_StatusList_FieldNumber) { + GtalkSharedStatus_StatusList_FieldNumber_Show = 7, + GtalkSharedStatus_StatusList_FieldNumber_StatusArray = 8, +}; + +@interface GtalkSharedStatus_StatusList : GPBMessage + + +@property(nonatomic, readwrite) GtalkSharedStatus_ShowType show; + +@property(nonatomic, readwrite) BOOL hasShow; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *statusArray; +/** The number of items in @c statusArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger statusArray_Count; + +@end + +#pragma mark - GtalkOtrQuery + +typedef GPB_ENUM(GtalkOtrQuery_FieldNumber) { + GtalkOtrQuery_FieldNumber_NosaveDefault = 1, + GtalkOtrQuery_FieldNumber_ItemArray = 2, + GtalkOtrQuery_FieldNumber_Etag = 3, + GtalkOtrQuery_FieldNumber_NotModified = 4, +}; + +@interface GtalkOtrQuery : GPBMessage + + +@property(nonatomic, readwrite) BOOL nosaveDefault; + +@property(nonatomic, readwrite) BOOL hasNosaveDefault; + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GtalkOtrItem*> *itemArray; +/** The number of items in @c itemArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger itemArray_Count; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *etag; +/** Test to see if @c etag has been set. */ +@property(nonatomic, readwrite) BOOL hasEtag; + + +@property(nonatomic, readwrite) BOOL notModified; + +@property(nonatomic, readwrite) BOOL hasNotModified; +@end + +#pragma mark - GtalkOtrItem + +typedef GPB_ENUM(GtalkOtrItem_FieldNumber) { + GtalkOtrItem_FieldNumber_Jid = 1, + GtalkOtrItem_FieldNumber_Nosave = 2, + GtalkOtrItem_FieldNumber_ChangedByBuddy = 3, +}; + +@interface GtalkOtrItem : GPBMessage + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *jid; +/** Test to see if @c jid has been set. */ +@property(nonatomic, readwrite) BOOL hasJid; + + +@property(nonatomic, readwrite) BOOL nosave; + +@property(nonatomic, readwrite) BOOL hasNosave; + +@property(nonatomic, readwrite) BOOL changedByBuddy; + +@property(nonatomic, readwrite) BOOL hasChangedByBuddy; +@end + +#pragma mark - GtalkIdle + +typedef GPB_ENUM(GtalkIdle_FieldNumber) { + GtalkIdle_FieldNumber_Idle = 1, + GtalkIdle_FieldNumber_Away = 2, +}; + +@interface GtalkIdle : GPBMessage + + +@property(nonatomic, readwrite) BOOL idle; + +@property(nonatomic, readwrite) BOOL hasIdle; + +@property(nonatomic, readwrite) BOOL away; + +@property(nonatomic, readwrite) BOOL hasAway; +@end + +#pragma mark - GtalkPostAuthBatchQuery + +typedef GPB_ENUM(GtalkPostAuthBatchQuery_FieldNumber) { + GtalkPostAuthBatchQuery_FieldNumber_Available = 1, + GtalkPostAuthBatchQuery_FieldNumber_DeviceIdle = 2, + GtalkPostAuthBatchQuery_FieldNumber_MobileIndicator = 3, + GtalkPostAuthBatchQuery_FieldNumber_SharedStatusVersion = 4, + GtalkPostAuthBatchQuery_FieldNumber_RosterEtag = 5, + GtalkPostAuthBatchQuery_FieldNumber_OtrEtag = 6, + GtalkPostAuthBatchQuery_FieldNumber_AvatarHash = 7, + GtalkPostAuthBatchQuery_FieldNumber_VcardQueryStanzaId = 8, + GtalkPostAuthBatchQuery_FieldNumber_CapabilitiesExtFlags = 9, +}; + +@interface GtalkPostAuthBatchQuery : GPBMessage + + +@property(nonatomic, readwrite) BOOL available; + +@property(nonatomic, readwrite) BOOL hasAvailable; + +@property(nonatomic, readwrite) BOOL deviceIdle; + +@property(nonatomic, readwrite) BOOL hasDeviceIdle; + +@property(nonatomic, readwrite) BOOL mobileIndicator; + +@property(nonatomic, readwrite) BOOL hasMobileIndicator; + +@property(nonatomic, readwrite) int32_t sharedStatusVersion; + +@property(nonatomic, readwrite) BOOL hasSharedStatusVersion; + +@property(nonatomic, readwrite, copy, null_resettable) NSString *rosterEtag; +/** Test to see if @c rosterEtag has been set. */ +@property(nonatomic, readwrite) BOOL hasRosterEtag; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *otrEtag; +/** Test to see if @c otrEtag has been set. */ +@property(nonatomic, readwrite) BOOL hasOtrEtag; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *avatarHash; +/** Test to see if @c avatarHash has been set. */ +@property(nonatomic, readwrite) BOOL hasAvatarHash; + + +@property(nonatomic, readwrite, copy, null_resettable) NSString *vcardQueryStanzaId; +/** Test to see if @c vcardQueryStanzaId has been set. */ +@property(nonatomic, readwrite) BOOL hasVcardQueryStanzaId; + + +@property(nonatomic, readwrite) int32_t capabilitiesExtFlags; + +@property(nonatomic, readwrite) BOOL hasCapabilitiesExtFlags; +@end + +#pragma mark - GtalkStreamAck + +@interface GtalkStreamAck : GPBMessage + +@end + +#pragma mark - GtalkSelectiveAck + +typedef GPB_ENUM(GtalkSelectiveAck_FieldNumber) { + GtalkSelectiveAck_FieldNumber_IdArray = 1, +}; + +@interface GtalkSelectiveAck : GPBMessage + + +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *idArray; +/** The number of items in @c idArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger idArray_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.m b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.m new file mode 100644 index 00000000..e41d4163 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Protos/GtalkExtensions.pbobjc.m @@ -0,0 +1,1407 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: buzz/mobile/proto/gtalk_extensions.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h> +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + + #import "GtalkExtensions.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - GtalkGtalkExtensionsRoot + +@implementation GtalkGtalkExtensionsRoot + +// No extensions in the file and no imports, so no need to generate +// +extensionRegistry. + +@end + +#pragma mark - GtalkGtalkExtensionsRoot_FileDescriptor + +static GPBFileDescriptor *GtalkGtalkExtensionsRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"mobilegtalk" + objcPrefix:@"Gtalk" + syntax:GPBFileSyntaxProto2]; + } + return descriptor; +} + +#pragma mark - GtalkRosterQuery + +@implementation GtalkRosterQuery + +@dynamic hasEtag, etag; +@dynamic hasNotModified, notModified; +@dynamic itemArray, itemArray_Count; +@dynamic hasAvatarWidth, avatarWidth; +@dynamic hasAvatarHeight, avatarHeight; + +typedef struct GtalkRosterQuery__storage_ { + uint32_t _has_storage_[1]; + int32_t avatarWidth; + int32_t avatarHeight; + NSString *etag; + NSMutableArray *itemArray; +} GtalkRosterQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "etag", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_Etag, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, etag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "notModified", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_NotModified, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "itemArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkRosterItem), + .number = GtalkRosterQuery_FieldNumber_ItemArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, itemArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "avatarWidth", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_AvatarWidth, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, avatarWidth), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt32, + }, + { + .name = "avatarHeight", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterQuery_FieldNumber_AvatarHeight, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkRosterQuery__storage_, avatarHeight), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRosterQuery class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRosterQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; +#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + static const char *extraTextFormatInfo = + "\002\004\013\000\005\014\000"; + [localDescriptor setupExtraTextInfo:extraTextFormatInfo]; +#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkRosterItem + +@implementation GtalkRosterItem + +@dynamic hasJid, jid; +@dynamic hasName, name; +@dynamic hasSubscription, subscription; +@dynamic hasAsk, ask; +@dynamic groupArray, groupArray_Count; +@dynamic hasQuickContact, quickContact; +@dynamic hasDisplay, display; +@dynamic hasRejected, rejected; + +typedef struct GtalkRosterItem__storage_ { + uint32_t _has_storage_[1]; + GtalkRosterItem_SubscriptionType subscription; + GtalkRosterItem_AskType ask; + GtalkRosterItem_DisplayType display; + NSString *jid; + NSString *name; + NSMutableArray *groupArray; +} GtalkRosterItem__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_Jid, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, jid), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_Name, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "subscription", + .dataTypeSpecific.enumDescFunc = GtalkRosterItem_SubscriptionType_EnumDescriptor, + .number = GtalkRosterItem_FieldNumber_Subscription, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, subscription), + .flags = (GPBFieldFlags)(GPBFieldRequired | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "ask", + .dataTypeSpecific.enumDescFunc = GtalkRosterItem_AskType_EnumDescriptor, + .number = GtalkRosterItem_FieldNumber_Ask, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, ask), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "groupArray", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_GroupArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, groupArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + { + .name = "quickContact", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_QuickContact, + .hasIndex = 4, + .offset = 5, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "display", + .dataTypeSpecific.enumDescFunc = GtalkRosterItem_DisplayType_EnumDescriptor, + .number = GtalkRosterItem_FieldNumber_Display, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkRosterItem__storage_, display), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "rejected", + .dataTypeSpecific.className = NULL, + .number = GtalkRosterItem_FieldNumber_Rejected, + .hasIndex = 7, + .offset = 8, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRosterItem class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRosterItem__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkRosterItem_SubscriptionType + +GPBEnumDescriptor *GtalkRosterItem_SubscriptionType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "None\000To\000From\000Both\000Remove\000"; + static const int32_t values[] = { + GtalkRosterItem_SubscriptionType_None, + GtalkRosterItem_SubscriptionType_To, + GtalkRosterItem_SubscriptionType_From, + GtalkRosterItem_SubscriptionType_Both, + GtalkRosterItem_SubscriptionType_Remove, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkRosterItem_SubscriptionType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkRosterItem_SubscriptionType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkRosterItem_SubscriptionType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkRosterItem_SubscriptionType_None: + case GtalkRosterItem_SubscriptionType_To: + case GtalkRosterItem_SubscriptionType_From: + case GtalkRosterItem_SubscriptionType_Both: + case GtalkRosterItem_SubscriptionType_Remove: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkRosterItem_AskType + +GPBEnumDescriptor *GtalkRosterItem_AskType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Subscribe\000"; + static const int32_t values[] = { + GtalkRosterItem_AskType_Subscribe, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkRosterItem_AskType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkRosterItem_AskType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkRosterItem_AskType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkRosterItem_AskType_Subscribe: + return YES; + default: + return NO; + } +} + +#pragma mark - Enum GtalkRosterItem_DisplayType + +GPBEnumDescriptor *GtalkRosterItem_DisplayType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Blocked\000Hidden\000Pinned\000"; + static const int32_t values[] = { + GtalkRosterItem_DisplayType_Blocked, + GtalkRosterItem_DisplayType_Hidden, + GtalkRosterItem_DisplayType_Pinned, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkRosterItem_DisplayType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkRosterItem_DisplayType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkRosterItem_DisplayType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkRosterItem_DisplayType_Blocked: + case GtalkRosterItem_DisplayType_Hidden: + case GtalkRosterItem_DisplayType_Pinned: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkRmqLastId + +@implementation GtalkRmqLastId + +@dynamic hasId_p, id_p; + +typedef struct GtalkRmqLastId__storage_ { + uint32_t _has_storage_[1]; + int64_t id_p; +} GtalkRmqLastId__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkRmqLastId_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRmqLastId__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRmqLastId class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRmqLastId__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkRmqAck + +@implementation GtalkRmqAck + +@dynamic hasId_p, id_p; + +typedef struct GtalkRmqAck__storage_ { + uint32_t _has_storage_[1]; + int64_t id_p; +} GtalkRmqAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "id_p", + .dataTypeSpecific.className = NULL, + .number = GtalkRmqAck_FieldNumber_Id_p, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkRmqAck__storage_, id_p), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeInt64, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkRmqAck class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkRmqAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkVCard + +@implementation GtalkVCard + +@dynamic hasVersion, version; +@dynamic hasFullName, fullName; +@dynamic hasPhoto, photo; +@dynamic hasAvatarHash, avatarHash; +@dynamic hasModified, modified; + +typedef struct GtalkVCard__storage_ { + uint32_t _has_storage_[1]; + NSString *version; + NSString *fullName; + GtalkPhoto *photo; + NSString *avatarHash; +} GtalkVCard__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "version", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_Version, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, version), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "fullName", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_FullName, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, fullName), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "photo", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkPhoto), + .number = GtalkVCard_FieldNumber_Photo, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, photo), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "avatarHash", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_AvatarHash, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkVCard__storage_, avatarHash), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "modified", + .dataTypeSpecific.className = NULL, + .number = GtalkVCard_FieldNumber_Modified, + .hasIndex = 4, + .offset = 5, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkVCard class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkVCard__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkPhoto + +@implementation GtalkPhoto + +@dynamic hasType, type; +@dynamic hasData_p, data_p; + +typedef struct GtalkPhoto__storage_ { + uint32_t _has_storage_[1]; + NSString *type; + NSString *data_p; +} GtalkPhoto__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "type", + .dataTypeSpecific.className = NULL, + .number = GtalkPhoto_FieldNumber_Type, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkPhoto__storage_, type), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "data_p", + .dataTypeSpecific.className = NULL, + .number = GtalkPhoto_FieldNumber_Data_p, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkPhoto__storage_, data_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkPhoto class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkPhoto__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkChatRead + +@implementation GtalkChatRead + +@dynamic hasUser, user; + +typedef struct GtalkChatRead__storage_ { + uint32_t _has_storage_[1]; + NSString *user; +} GtalkChatRead__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkChatRead_FieldNumber_User, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkChatRead__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkChatRead class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkChatRead__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkChatClosed + +@implementation GtalkChatClosed + +@dynamic hasUser, user; + +typedef struct GtalkChatClosed__storage_ { + uint32_t _has_storage_[1]; + NSString *user; +} GtalkChatClosed__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "user", + .dataTypeSpecific.className = NULL, + .number = GtalkChatClosed_FieldNumber_User, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkChatClosed__storage_, user), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkChatClosed class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkChatClosed__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkCapabilities + +@implementation GtalkCapabilities + +@dynamic hasNode, node; +@dynamic hasVer, ver; +@dynamic hasExt, ext; +@dynamic hasHash_p, hash_p; + +typedef struct GtalkCapabilities__storage_ { + uint32_t _has_storage_[1]; + NSString *node; + NSString *ver; + NSString *ext; + NSString *hash_p; +} GtalkCapabilities__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "node", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Node, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, node), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "ver", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Ver, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, ver), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "ext", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Ext, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, ext), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "hash_p", + .dataTypeSpecific.className = NULL, + .number = GtalkCapabilities_FieldNumber_Hash_p, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkCapabilities__storage_, hash_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkCapabilities class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkCapabilities__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkSharedStatus + +@implementation GtalkSharedStatus + +@dynamic hasStatusMax, statusMax; +@dynamic hasStatusListMax, statusListMax; +@dynamic hasStatusListContentsMax, statusListContentsMax; +@dynamic hasStatus, status; +@dynamic hasShow, show; +@dynamic statusListArray, statusListArray_Count; +@dynamic hasInvisible, invisible; +@dynamic hasStatusMinVersion, statusMinVersion; + +typedef struct GtalkSharedStatus__storage_ { + uint32_t _has_storage_[1]; + int32_t statusMax; + int32_t statusListMax; + int32_t statusListContentsMax; + GtalkSharedStatus_ShowType show; + int32_t statusMinVersion; + NSString *status; + NSMutableArray *statusListArray; +} GtalkSharedStatus__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "statusMax", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusMax, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusMax), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "statusListMax", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusListMax, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusListMax), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "statusListContentsMax", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusListContentsMax, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusListContentsMax), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "status", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_Status, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, status), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "show", + .dataTypeSpecific.enumDescFunc = GtalkSharedStatus_ShowType_EnumDescriptor, + .number = GtalkSharedStatus_FieldNumber_Show, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, show), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "statusListArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkSharedStatus_StatusList), + .number = GtalkSharedStatus_FieldNumber_StatusListArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusListArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeGroup, + }, + { + .name = "invisible", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_Invisible, + .hasIndex = 5, + .offset = 6, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "statusMinVersion", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_FieldNumber_StatusMinVersion, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkSharedStatus__storage_, statusMinVersion), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSharedStatus class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSharedStatus__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkSharedStatus_ShowType + +GPBEnumDescriptor *GtalkSharedStatus_ShowType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "Default\000Dnd\000"; + static const int32_t values[] = { + GtalkSharedStatus_ShowType_Default, + GtalkSharedStatus_ShowType_Dnd, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkSharedStatus_ShowType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkSharedStatus_ShowType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkSharedStatus_ShowType_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkSharedStatus_ShowType_Default: + case GtalkSharedStatus_ShowType_Dnd: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkSharedStatus_StatusList + +@implementation GtalkSharedStatus_StatusList + +@dynamic hasShow, show; +@dynamic statusArray, statusArray_Count; + +typedef struct GtalkSharedStatus_StatusList__storage_ { + uint32_t _has_storage_[1]; + GtalkSharedStatus_ShowType show; + NSMutableArray *statusArray; +} GtalkSharedStatus_StatusList__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "show", + .dataTypeSpecific.enumDescFunc = GtalkSharedStatus_ShowType_EnumDescriptor, + .number = GtalkSharedStatus_StatusList_FieldNumber_Show, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkSharedStatus_StatusList__storage_, show), + .flags = (GPBFieldFlags)(GPBFieldRequired | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "statusArray", + .dataTypeSpecific.className = NULL, + .number = GtalkSharedStatus_StatusList_FieldNumber_StatusArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkSharedStatus_StatusList__storage_, statusArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSharedStatus_StatusList class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSharedStatus_StatusList__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GtalkSharedStatus)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkOtrQuery + +@implementation GtalkOtrQuery + +@dynamic hasNosaveDefault, nosaveDefault; +@dynamic itemArray, itemArray_Count; +@dynamic hasEtag, etag; +@dynamic hasNotModified, notModified; + +typedef struct GtalkOtrQuery__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *itemArray; + NSString *etag; +} GtalkOtrQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "nosaveDefault", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrQuery_FieldNumber_NosaveDefault, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "itemArray", + .dataTypeSpecific.className = GPBStringifySymbol(GtalkOtrItem), + .number = GtalkOtrQuery_FieldNumber_ItemArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkOtrQuery__storage_, itemArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "etag", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrQuery_FieldNumber_Etag, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GtalkOtrQuery__storage_, etag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "notModified", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrQuery_FieldNumber_NotModified, + .hasIndex = 3, + .offset = 4, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkOtrQuery class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkOtrQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkOtrItem + +@implementation GtalkOtrItem + +@dynamic hasJid, jid; +@dynamic hasNosave, nosave; +@dynamic hasChangedByBuddy, changedByBuddy; + +typedef struct GtalkOtrItem__storage_ { + uint32_t _has_storage_[1]; + NSString *jid; +} GtalkOtrItem__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "jid", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrItem_FieldNumber_Jid, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GtalkOtrItem__storage_, jid), + .flags = GPBFieldRequired, + .dataType = GPBDataTypeString, + }, + { + .name = "nosave", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrItem_FieldNumber_Nosave, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "changedByBuddy", + .dataTypeSpecific.className = NULL, + .number = GtalkOtrItem_FieldNumber_ChangedByBuddy, + .hasIndex = 3, + .offset = 4, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkOtrItem class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkOtrItem__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkIdle + +@implementation GtalkIdle + +@dynamic hasIdle, idle; +@dynamic hasAway, away; + +typedef struct GtalkIdle__storage_ { + uint32_t _has_storage_[1]; +} GtalkIdle__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "idle", + .dataTypeSpecific.className = NULL, + .number = GtalkIdle_FieldNumber_Idle, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "away", + .dataTypeSpecific.className = NULL, + .number = GtalkIdle_FieldNumber_Away, + .hasIndex = 2, + .offset = 3, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkIdle class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkIdle__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkPostAuthBatchQuery + +@implementation GtalkPostAuthBatchQuery + +@dynamic hasAvailable, available; +@dynamic hasDeviceIdle, deviceIdle; +@dynamic hasMobileIndicator, mobileIndicator; +@dynamic hasSharedStatusVersion, sharedStatusVersion; +@dynamic hasRosterEtag, rosterEtag; +@dynamic hasOtrEtag, otrEtag; +@dynamic hasAvatarHash, avatarHash; +@dynamic hasVcardQueryStanzaId, vcardQueryStanzaId; +@dynamic hasCapabilitiesExtFlags, capabilitiesExtFlags; + +typedef struct GtalkPostAuthBatchQuery__storage_ { + uint32_t _has_storage_[1]; + int32_t sharedStatusVersion; + int32_t capabilitiesExtFlags; + NSString *rosterEtag; + NSString *otrEtag; + NSString *avatarHash; + NSString *vcardQueryStanzaId; +} GtalkPostAuthBatchQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "available", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_Available, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldRequired, + .dataType = GPBDataTypeBool, + }, + { + .name = "deviceIdle", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_DeviceIdle, + .hasIndex = 2, + .offset = 3, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "mobileIndicator", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_MobileIndicator, + .hasIndex = 4, + .offset = 5, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "sharedStatusVersion", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_SharedStatusVersion, + .hasIndex = 6, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, sharedStatusVersion), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "rosterEtag", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_RosterEtag, + .hasIndex = 7, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, rosterEtag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "otrEtag", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_OtrEtag, + .hasIndex = 8, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, otrEtag), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "avatarHash", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_AvatarHash, + .hasIndex = 9, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, avatarHash), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "vcardQueryStanzaId", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_VcardQueryStanzaId, + .hasIndex = 10, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, vcardQueryStanzaId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "capabilitiesExtFlags", + .dataTypeSpecific.className = NULL, + .number = GtalkPostAuthBatchQuery_FieldNumber_CapabilitiesExtFlags, + .hasIndex = 11, + .offset = (uint32_t)offsetof(GtalkPostAuthBatchQuery__storage_, capabilitiesExtFlags), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkPostAuthBatchQuery class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkPostAuthBatchQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GtalkPostAuthBatchQuery_CapabilitiesExtFlags + +GPBEnumDescriptor *GtalkPostAuthBatchQuery_CapabilitiesExtFlags_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "HasVoiceV1\000HasVideoV1\000HasCameraV1\000HasPmu" + "cV1\000"; + static const int32_t values[] = { + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVoiceV1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVideoV1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasCameraV1, + GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasPmucV1, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GtalkPostAuthBatchQuery_CapabilitiesExtFlags) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GtalkPostAuthBatchQuery_CapabilitiesExtFlags_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GtalkPostAuthBatchQuery_CapabilitiesExtFlags_IsValidValue(int32_t value__) { + switch (value__) { + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVoiceV1: + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasVideoV1: + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasCameraV1: + case GtalkPostAuthBatchQuery_CapabilitiesExtFlags_HasPmucV1: + return YES; + default: + return NO; + } +} + +#pragma mark - GtalkStreamAck + +@implementation GtalkStreamAck + + +typedef struct GtalkStreamAck__storage_ { + uint32_t _has_storage_[1]; +} GtalkStreamAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkStreamAck class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:NULL + fieldCount:0 + storageSize:sizeof(GtalkStreamAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GtalkSelectiveAck + +@implementation GtalkSelectiveAck + +@dynamic idArray, idArray_Count; + +typedef struct GtalkSelectiveAck__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *idArray; +} GtalkSelectiveAck__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "idArray", + .dataTypeSpecific.className = NULL, + .number = GtalkSelectiveAck_FieldNumber_IdArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GtalkSelectiveAck__storage_, idArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GtalkSelectiveAck class] + rootClass:[GtalkGtalkExtensionsRoot class] + file:GtalkGtalkExtensionsRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GtalkSelectiveAck__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FIRMessaging.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FIRMessaging.h new file mode 100644 index 00000000..71a4b5e5 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FIRMessaging.h @@ -0,0 +1,508 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + * @related FIRMessaging + * + * The completion handler invoked when the registration token returns. + * If the call fails we return the appropriate `error code`, described by + * `FIRMessagingError`. + * + * @param FCMToken The valid registration token returned by FCM. + * @param error The error describing why a token request failed. The error code + * will match a value from the FIRMessagingError enumeration. + */ +typedef void (^FIRMessagingFCMTokenFetchCompletion)(NSString *_Nullable FCMToken, + NSError *_Nullable error) + NS_SWIFT_NAME(MessagingFCMTokenFetchCompletion); + +/** + * @related FIRMessaging + * + * The completion handler invoked when the registration token deletion request is + * completed. If the call fails we return the appropriate `error code`, described + * by `FIRMessagingError`. + * + * @param error The error describing why a token deletion failed. The error code + * will match a value from the FIRMessagingError enumeration. + */ +typedef void (^FIRMessagingDeleteFCMTokenCompletion)(NSError *_Nullable error) + NS_SWIFT_NAME(MessagingDeleteFCMTokenCompletion); + +/** + * Callback to invoke once the HTTP call to FIRMessaging backend for updating + * subscription finishes. + * + * @param error The error which occurred while updating the subscription topic + * on the FIRMessaging server. This will be nil in case the operation + * was successful, or if the operation was cancelled. + */ +typedef void (^FIRMessagingTopicOperationCompletion)(NSError *_Nullable error); + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +/** + * Notification sent when the upstream message has been delivered + * successfully to the server. The notification object will be the messageID + * of the successfully delivered message. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingSendSuccessNotification + NS_SWIFT_NAME(MessagingSendSuccess) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when the upstream message was failed to be sent to the + * server. The notification object will be the messageID of the failed + * message. The userInfo dictionary will contain the relevant error + * information for the failure. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingSendErrorNotification + NS_SWIFT_NAME(MessagingSendError) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when the Firebase messaging server deletes pending + * messages due to exceeded storage limits. This may occur, for example, when + * the device cannot be reached for an extended period of time. + * + * It is recommended to retrieve any missing messages directly from the + * server. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingMessagesDeletedNotification + NS_SWIFT_NAME(MessagingMessagesDeleted) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when Firebase Messaging establishes or disconnects from + * an FCM socket connection. You can query the connection state in this + * notification by checking the `isDirectChannelEstablished` property of FIRMessaging. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingConnectionStateChangedNotification + NS_SWIFT_NAME(MessagingConnectionStateChanged) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when the FCM registration token has been refreshed. Please use the + * FIRMessaging delegate method `messaging:didReceiveRegistrationToken:` to receive current and + * updated tokens. + */ +FOUNDATION_EXPORT const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification + NS_SWIFT_NAME(MessagingRegistrationTokenRefreshed); +#else +/** + * Notification sent when the upstream message has been delivered + * successfully to the server. The notification object will be the messageID + * of the successfully delivered message. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingSendSuccessNotification + NS_SWIFT_NAME(MessagingSendSuccessNotification) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when the upstream message was failed to be sent to the + * server. The notification object will be the messageID of the failed + * message. The userInfo dictionary will contain the relevant error + * information for the failure. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingSendErrorNotification + NS_SWIFT_NAME(MessagingSendErrorNotification) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when the Firebase messaging server deletes pending + * messages due to exceeded storage limits. This may occur, for example, when + * the device cannot be reached for an extended period of time. + * + * It is recommended to retrieve any missing messages directly from the + * server. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingMessagesDeletedNotification + NS_SWIFT_NAME(MessagingMessagesDeletedNotification) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when Firebase Messaging establishes or disconnects from + * an FCM socket connection. You can query the connection state in this + * notification by checking the `isDirectChannelEstablished` property of FIRMessaging. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingConnectionStateChangedNotification + NS_SWIFT_NAME(MessagingConnectionStateChangedNotification) DEPRECATED_ATTRIBUTE; + +/** + * Notification sent when the FCM registration token has been refreshed. Please use the + * FIRMessaging delegate method `messaging:didReceiveRegistrationToken:` to receive current and + * updated tokens. + */ +FOUNDATION_EXPORT NSString *const FIRMessagingRegistrationTokenRefreshedNotification + NS_SWIFT_NAME(MessagingRegistrationTokenRefreshedNotification); +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +/** + * @enum FIRMessagingError + */ +typedef NS_ENUM(NSUInteger, FIRMessagingError) { + /// Unknown error. + FIRMessagingErrorUnknown = 0, + + /// FIRMessaging couldn't validate request from this client. + FIRMessagingErrorAuthentication = 1, + + /// InstanceID service cannot be accessed. + FIRMessagingErrorNoAccess = 2, + + /// Request to InstanceID backend timed out. + FIRMessagingErrorTimeout = 3, + + /// No network available to reach the servers. + FIRMessagingErrorNetwork = 4, + + /// Another similar operation in progress, bailing this one. + FIRMessagingErrorOperationInProgress = 5, + + /// Some parameters of the request were invalid. + FIRMessagingErrorInvalidRequest = 7, + + /// Topic name is invalid for subscription/unsubscription. + FIRMessagingErrorInvalidTopicName = 8, + +} NS_SWIFT_NAME(MessagingError); + +/// Status for the downstream message received by the app. +typedef NS_ENUM(NSInteger, FIRMessagingMessageStatus) { + /// Unknown status. + FIRMessagingMessageStatusUnknown, + /// New downstream message received by the app. + FIRMessagingMessageStatusNew, +} NS_SWIFT_NAME(MessagingMessageStatus); + +/** + * The APNS token type for the app. If the token type is set to `UNKNOWN` + * Firebase Messaging will implicitly try to figure out what the actual token type + * is from the provisioning profile. + * Unless you really need to specify the type, you should use the `APNSToken` + * property instead. + */ +typedef NS_ENUM(NSInteger, FIRMessagingAPNSTokenType) { + /// Unknown token type. + FIRMessagingAPNSTokenTypeUnknown, + /// Sandbox token type. + FIRMessagingAPNSTokenTypeSandbox, + /// Production token type. + FIRMessagingAPNSTokenTypeProd, +} NS_SWIFT_NAME(MessagingAPNSTokenType); + +/// Information about a downstream message received by the app. +NS_SWIFT_NAME(MessagingMessageInfo) +@interface FIRMessagingMessageInfo : NSObject + +/// The status of the downstream message +@property(nonatomic, readonly, assign) FIRMessagingMessageStatus status; + +@end + +/** + * A remote data message received by the app via FCM (not just the APNs interface). + * + * This is only for devices running iOS 10 or above. To support devices running iOS 9 or below, use + * the local and remote notifications handlers defined in UIApplicationDelegate protocol. + */ +NS_SWIFT_NAME(MessagingRemoteMessage) +__deprecated_msg( + "FCM direct channel is deprecated, please use APNs for downstream message handling.") + @interface FIRMessagingRemoteMessage : NSObject + +/// The message ID of downstream message. +@property(nonatomic, readonly, copy) NSString *messageID DEPRECATED_ATTRIBUTE; +/// The downstream message received by the application. +@property(nonatomic, readonly, strong) NSDictionary *appData DEPRECATED_ATTRIBUTE; + +@end + +@class FIRMessaging; +@class FIRMessagingExtensionHelper; + +/** + * A protocol to handle token update or data message delivery from FCM. + * + */ +NS_SWIFT_NAME(MessagingDelegate) +@protocol FIRMessagingDelegate <NSObject> + +@optional +/// This method will be called once a token is available, or has been refreshed. Typically it +/// will be called once per app start, but may be called more often, if token is invalidated or +/// updated. In this method, you should perform operations such as: +/// +/// * Uploading the FCM token to your application server, so targeted notifications can be sent. +/// +/// * Subscribing to any topics. +- (void)messaging:(FIRMessaging *)messaging + didReceiveRegistrationToken:(NSString *)fcmToken + NS_SWIFT_NAME(messaging(_:didReceiveRegistrationToken:)); + +/// Handle data messages received via FCM direct channel (not via APNS). +- (void)messaging:(FIRMessaging *)messaging + didReceiveMessage:(FIRMessagingRemoteMessage *)remoteMessage + NS_SWIFT_NAME(messaging(_:didReceive:))__deprecated_msg( + "FCM direct channel is deprecated, please use APNs for downstream message handling."); +@end + +/** + * Firebase Messaging lets you reliably deliver messages at no cost. + * + * To send or receive messages, the app must get a + * registration token from FIRInstanceID. This token authorizes an + * app server to send messages to an app instance. + * + * In order to receive FIRMessaging messages, declare + * `application:didReceiveRemoteNotification::fetchCompletionHandler:`. + */ +NS_SWIFT_NAME(Messaging) +@interface FIRMessaging : NSObject + +/** + * Delegate to handle FCM token refreshes, and remote data messages received via FCM direct channel. + */ +@property(nonatomic, weak, nullable) id<FIRMessagingDelegate> delegate; + +/** + * When set to `YES`, Firebase Messaging will automatically establish a socket-based, direct + * channel to the FCM server. Enable this only if you are sending upstream messages or + * receiving non-APNS, data-only messages in foregrounded apps. + * Default is `NO`. + */ +@property(nonatomic) BOOL shouldEstablishDirectChannel DEPRECATED_MSG_ATTRIBUTE( + "FCM direct channel is deprecated, please use APNs channel for downstream message delivery."); + +/** + * Returns `YES` if the direct channel to the FCM server is active, and `NO` otherwise. + */ +@property(nonatomic, readonly) BOOL isDirectChannelEstablished DEPRECATED_MSG_ATTRIBUTE( + "FCM direct channel is deprecated, please use APNs channel for downstream message delivery."); + +/** + * FIRMessaging + * + * @return An instance of FIRMessaging. + */ ++ (instancetype)messaging NS_SWIFT_NAME(messaging()); + +/** + * FIRMessagingExtensionHelper + * + * Use FIRMessagingExtensionHelper to populate rich UI contents for your notifications. + * e.g. If an image URL is set in your notification payload or on the console, call + * FIRMessagingExtensionHelper API to render it on your notification. + * + * @return An instance of FIRMessagingExtensionHelper that handles the extensions API. + */ ++ (FIRMessagingExtensionHelper *)extensionHelper NS_SWIFT_NAME(serviceExtension()) + NS_AVAILABLE(10.14, 10.0); + +/** + * Unavailable. Use +messaging instead. + */ +- (instancetype)init __attribute__((unavailable("Use +messaging instead."))); + +#pragma mark - APNS + +/** + * This property is used to set the APNS Token received by the application delegate. + * + * FIRMessaging uses method swizzling to ensure that the APNS token is set + * automatically. However, if you have disabled swizzling by setting + * `FirebaseAppDelegateProxyEnabled` to `NO` in your app's + * Info.plist, you should manually set the APNS token in your application + * delegate's `-application:didRegisterForRemoteNotificationsWithDeviceToken:` + * method. + * + * If you would like to set the type of the APNS token, rather than relying on + * automatic detection, see: `-setAPNSToken:type:`. + */ +@property(nonatomic, copy, nullable) NSData *APNSToken NS_SWIFT_NAME(apnsToken); + +/** + * Set APNS token for the application. This APNS token will be used to register + * with Firebase Messaging using `FCMToken` or + * `tokenWithAuthorizedEntity:scope:options:handler`. + * + * @param apnsToken The APNS token for the application. + * @param type The type of APNS token. Debug builds should use + * FIRMessagingAPNSTokenTypeSandbox. Alternatively, you can supply + * FIRMessagingAPNSTokenTypeUnknown to have the type automatically + * detected based on your provisioning profile. + */ +- (void)setAPNSToken:(NSData *)apnsToken type:(FIRMessagingAPNSTokenType)type; + +#pragma mark - FCM Tokens + +/** + * Is Firebase Messaging token auto generation enabled? If this flag is disabled, + * Firebase Messaging will not generate token automatically for message delivery. + * + * If this flag is disabled, Firebase Messaging does not generate new tokens automatically for + * message delivery. If this flag is enabled, FCM generates a registration token on application + * start when there is no existing valid token. FCM also generates a new token when an existing + * token is deleted. + * + * This setting is persisted, and is applied on future + * invocations of your application. Once explicitly set, it overrides any + * settings in your Info.plist. + * + * By default, FCM automatic initialization is enabled. If you need to change the + * default (for example, because you want to prompt the user before getting token) + * set FirebaseMessagingAutoInitEnabled to false in your application's Info.plist. + */ +@property(nonatomic, assign, getter=isAutoInitEnabled) BOOL autoInitEnabled; + +/** + * The FCM token is used to identify this device so that FCM can send notifications to it. + * It is associated with your APNS token when the APNS token is supplied, so that sending + * messages to the FCM token will be delivered over APNS. + * + * The FCM token is sometimes refreshed automatically. In your FIRMessaging delegate, the + * delegate method `messaging:didReceiveRegistrationToken:` will be called once a token is + * available, or has been refreshed. Typically it should be called once per app start, but + * may be called more often, if token is invalidated or updated. + * + * Once you have an FCM token, you should send it to your application server, so it can use + * the FCM token to send notifications to your device. + */ +@property(nonatomic, readonly, nullable) NSString *FCMToken NS_SWIFT_NAME(fcmToken); + +/** + * Retrieves an FCM registration token for a particular Sender ID. This can be used to allow + * multiple senders to send notifications to the same device. By providing a different Sender + * ID than your default when fetching a token, you can create a new FCM token which you can + * give to a different sender. Both tokens will deliver notifications to your device, and you + * can revoke a token when you need to. + * + * This registration token is not cached by FIRMessaging. FIRMessaging should have an APNS + * token set before calling this to ensure that notifications can be delivered via APNS using + * this FCM token. You may re-retrieve the FCM token once you have the APNS token set, to + * associate it with the FCM token. The default FCM token is automatically associated with + * the APNS token, if the APNS token data is available. + * + * @param senderID The Sender ID for a particular Firebase project. + * @param completion The completion handler to handle the token request. + */ +- (void)retrieveFCMTokenForSenderID:(NSString *)senderID + completion:(FIRMessagingFCMTokenFetchCompletion)completion + NS_SWIFT_NAME(retrieveFCMToken(forSenderID:completion:)); + +/** + * Invalidates an FCM token for a particular Sender ID. That Sender ID cannot no longer send + * notifications to that FCM token. + * + * @param senderID The senderID for a particular Firebase project. + * @param completion The completion handler to handle the token deletion. + */ +- (void)deleteFCMTokenForSenderID:(NSString *)senderID + completion:(FIRMessagingDeleteFCMTokenCompletion)completion + NS_SWIFT_NAME(deleteFCMToken(forSenderID:completion:)); + +#pragma mark - Topics + +/** + * Asynchronously subscribes to a topic. This uses a FCM Token to identify + * the app instance and periodically sends data to the Firebase backend. To stop this, see + * `[FIRInstanceID deleteIDWithHandler:]`. + * + * @param topic The name of the topic, for example, @"sports". + */ +- (void)subscribeToTopic:(NSString *)topic NS_SWIFT_NAME(subscribe(toTopic:)); + +/** + * Asynchronously subscribe to the provided topic, retrying on failure. This uses a FCM Token + * to identify the app instance and periodically sends data to the Firebase backend. To stop this, + * see `[FIRInstanceID deleteIDWithHandler:]`. + * + * @param topic The topic name to subscribe to, for example, @"sports". + * @param completion The completion that is invoked once the subscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)subscribeToTopic:(nonnull NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion; + +/** + * Asynchronously unsubscribe from a topic. This uses a FCM Token + * to identify the app instance and periodically sends data to the Firebase backend. To stop this, + * see `[FIRInstanceID deleteIDWithHandler:]`. + * + * @param topic The name of the topic, for example @"sports". + */ +- (void)unsubscribeFromTopic:(NSString *)topic NS_SWIFT_NAME(unsubscribe(fromTopic:)); + +/** + * Asynchronously unsubscribe from the provided topic, retrying on failure. This uses a FCM Token + * to identify the app instance and periodically sends data to the Firebase backend. To stop this, + * see `[FIRInstanceID deleteIDWithHandler:]`. + * + * @param topic The topic name to unsubscribe from, for example @"sports". + * @param completion The completion that is invoked once the unsubscribe call ends. + * In case of success, nil error is returned. Otherwise, an + * appropriate error object is returned. + */ +- (void)unsubscribeFromTopic:(nonnull NSString *)topic + completion:(nullable FIRMessagingTopicOperationCompletion)completion; + +#pragma mark - Upstream + +/** + * Sends an upstream ("device to cloud") message. + * + * The message is queued if we don't have an active connection. + * You can only use the upstream feature if your FCM implementation + * uses the XMPP server protocol. + * + * @param message Key/Value pairs to be sent. Values must be String, any + * other type will be ignored. + * @param receiver A string identifying the receiver of the message. For FCM + * project IDs the value is `SENDER_ID@gcm.googleapis.com`. + * @param messageID The ID of the message. This is generated by the application. It + * must be unique for each message generated by this application. + * It allows error callbacks and debugging, to uniquely identify + * each message. + * @param ttl The time to live for the message. In case we aren't able to + * send the message before the TTL expires we will send you a + * callback. If 0, we'll attempt to send immediately and return + * an error if we're not connected. Otherwise, the message will + * be queued. As for server-side messages, we don't return an error + * if the message has been dropped because of TTL; this can happen + * on the server side, and it would require extra communication. + */ +- (void)sendMessage:(NSDictionary *)message + to:(NSString *)receiver + withMessageID:(NSString *)messageID + timeToLive:(int64_t)ttl + __deprecated_msg("Upstream messaging through direct channel is deprecated. For realtime " + "updates, use Cloud Firestore, Realtime Database, or other services. "); + +#pragma mark - Analytics + +/** + * Use this to track message delivery and analytics for messages, typically + * when you receive a notification in `application:didReceiveRemoteNotification:`. + * However, you only need to call this if you set the `FirebaseAppDelegateProxyEnabled` + * flag to `NO` in your Info.plist. If `FirebaseAppDelegateProxyEnabled` is either missing + * or set to `YES` in your Info.plist, the library will call this automatically. + * + * @param message The downstream message received by the application. + * + * @return Information about the downstream message. + */ +- (FIRMessagingMessageInfo *)appDidReceiveMessage:(NSDictionary *)message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FIRMessagingExtensionHelper.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FIRMessagingExtensionHelper.h new file mode 100644 index 00000000..b2e3c775 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FIRMessagingExtensionHelper.h @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \ + __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 +#import <UserNotifications/UserNotifications.h> +#endif + +NS_ASSUME_NONNULL_BEGIN + +/// This class is used to automatically populate a notification with an image if it is +/// specified in the notification body via the `image` parameter. Images and other +/// rich content can be populated manually without the use of this class. See the +/// `UNNotificationServiceExtension` type for more details. +__IOS_AVAILABLE(10.0) __OSX_AVAILABLE(10.14) @interface FIRMessagingExtensionHelper : NSObject + +/// Call this API to complete your notification content modification. If you like to +/// overwrite some properties of the content instead of using the default payload, +/// make sure to make your customized motification to the content before passing it to +/// this call. +- (void)populateNotificationContent:(UNMutableNotificationContent *)content + withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FirebaseMessaging.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FirebaseMessaging.h new file mode 100755 index 00000000..a4def060 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/FirebaseMessaging/Sources/Public/FirebaseMessaging.h @@ -0,0 +1,18 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <FirebaseMessaging/FIRMessaging.h> +#import <FirebaseMessaging/FIRMessagingExtensionHelper.h> diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h new file mode 100644 index 00000000..b15925f4 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/AppDelegateSwizzler/Private/GULAppDelegateSwizzler.h @@ -0,0 +1,111 @@ +/* + * Copyright 2018 Google LLC + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#if SWIFT_PACKAGE +#import "GoogleUtilities/AppDelegateSwizzler/Private/GULApplication.h" +#else +#import <GoogleUtilities/GULApplication.h> +#endif + +NS_ASSUME_NONNULL_BEGIN + +typedef NSString *const GULAppDelegateInterceptorID; + +/** This class contains methods that isa swizzle the app delegate. */ +@interface GULAppDelegateSwizzler : NSProxy + +/** Registers an app delegate interceptor whose methods will be invoked as they're invoked on the + * original app delegate. + * + * @param interceptor An instance of a class that conforms to the application delegate protocol. + * The interceptor is NOT retained. + * @return A unique GULAppDelegateInterceptorID if interceptor was successfully registered; nil + * if it fails. + */ ++ (nullable GULAppDelegateInterceptorID)registerAppDelegateInterceptor: + (id<GULApplicationDelegate>)interceptor; + +/** Unregisters an interceptor with the given ID if it exists. + * + * @param interceptorID The object that was generated when the interceptor was registered. + */ ++ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID; + +/** This method ensures that the original app delegate has been proxied. Call this before + * registering your interceptor. This method is safe to call multiple times (but it only proxies + * the app delegate once). + * + * This method doesn't proxy APNS related methods: + * @code + * - application:didRegisterForRemoteNotificationsWithDeviceToken: + * - application:didFailToRegisterForRemoteNotificationsWithError: + * - application:didReceiveRemoteNotification:fetchCompletionHandler: + * - application:didReceiveRemoteNotification: + * @endcode + * + * To proxy these methods use +[GULAppDelegateSwizzler + * proxyOriginalDelegateIncludingAPNSMethods]. The methods have to be proxied separately to + * avoid potential warnings from Apple review about missing Push Notification Entitlement (e.g. + * https://github.com/firebase/firebase-ios-sdk/issues/2807) + * + * The method has no effect for extensions. + * + * @see proxyOriginalDelegateIncludingAPNSMethods + */ ++ (void)proxyOriginalDelegate; + +/** This method ensures that the original app delegate has been proxied including APNS related + * methods. Call this before registering your interceptor. This method is safe to call multiple + * times (but it only proxies the app delegate once) or + * after +[GULAppDelegateSwizzler proxyOriginalDelegate] + * + * This method calls +[GULAppDelegateSwizzler proxyOriginalDelegate] under the hood. + * After calling this method the following App Delegate methods will be proxied in addition to + * the methods proxied by proxyOriginalDelegate: + * @code + * - application:didRegisterForRemoteNotificationsWithDeviceToken: + * - application:didFailToRegisterForRemoteNotificationsWithError: + * - application:didReceiveRemoteNotification:fetchCompletionHandler: + * - application:didReceiveRemoteNotification: + * @endcode + * + * The method has no effect for extensions. + * + * @see proxyOriginalDelegate + */ ++ (void)proxyOriginalDelegateIncludingAPNSMethods; + +/** Indicates whether app delegate proxy is explicitly disabled or enabled. Enabled by default. + * + * @return YES if AppDelegateProxy is Enabled, NO otherwise. + */ ++ (BOOL)isAppDelegateProxyEnabled; + +/** Returns the current sharedApplication. + * + * @return the current application instance if in an app, or nil if in extension or if it doesn't + * exist. + */ ++ (nullable GULApplication *)sharedApplication; + +/** Do not initialize this class. */ +- (instancetype)init NS_UNAVAILABLE; + +NS_ASSUME_NONNULL_END + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/AppDelegateSwizzler/Private/GULApplication.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/AppDelegateSwizzler/Private/GULApplication.h new file mode 100644 index 00000000..80672124 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/AppDelegateSwizzler/Private/GULApplication.h @@ -0,0 +1,50 @@ +/* + * Copyright 2019 Google LLC + * + * 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. + */ + +#import <Foundation/Foundation.h> + +#if TARGET_OS_IOS || TARGET_OS_TV + +#import <UIKit/UIKit.h> + +#define GULApplication UIApplication +#define GULApplicationDelegate UIApplicationDelegate +#define GULUserActivityRestoring UIUserActivityRestoring + +static NSString *const kGULApplicationClassName = @"UIApplication"; + +#elif TARGET_OS_OSX + +#import <AppKit/AppKit.h> + +#define GULApplication NSApplication +#define GULApplicationDelegate NSApplicationDelegate +#define GULUserActivityRestoring NSUserActivityRestoring + +static NSString *const kGULApplicationClassName = @"NSApplication"; + +#elif TARGET_OS_WATCH + +#import <WatchKit/WatchKit.h> + +// We match the according watchOS API but swizzling should not work in watch +#define GULApplication WKExtension +#define GULApplicationDelegate WKExtensionDelegate +#define GULUserActivityRestoring NSUserActivityRestoring + +static NSString *const kGULApplicationClassName = @"WKExtension"; + +#endif diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h new file mode 100644 index 00000000..2fb16226 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@interface GULAppEnvironmentUtil : NSObject + +/// Indicates whether the app is from Apple Store or not. Returns NO if the app is on simulator, +/// development environment or sideloaded. ++ (BOOL)isFromAppStore; + +/// Indicates whether the app is a Testflight app. Returns YES if the app has sandbox receipt. +/// Returns NO otherwise. ++ (BOOL)isAppStoreReceiptSandbox; + +/// Indicates whether the app is on simulator or not at runtime depending on the device +/// architecture. ++ (BOOL)isSimulator; + +/// The current device model. Returns an empty string if device model cannot be retrieved. ++ (NSString *)deviceModel; + +/// The current operating system version. Returns an empty string if the system version cannot be +/// retrieved. ++ (NSString *)systemVersion; + +/// Indicates whether it is running inside an extension or an app. ++ (BOOL)isAppExtension; + +/// @return Returns @YES when is run on iOS version greater or equal to 7.0 ++ (BOOL)isIOS7OrHigher DEPRECATED_MSG_ATTRIBUTE( + "Always `YES` because only iOS 8 and higher supported. The method will be removed."); + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULHeartbeatDateStorage.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULHeartbeatDateStorage.h new file mode 100644 index 00000000..9432dfc0 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULHeartbeatDateStorage.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/// Stores either a date or a dictionary to a specified file. +@interface GULHeartbeatDateStorage : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@property(nonatomic, readonly) NSURL *fileURL; + +/** + * Default initializer. + * @param fileName The name of the file to store the date information. + * exist, it will be created if needed. + */ +- (instancetype)initWithFileName:(NSString *)fileName; + +/** + * Reads the date from the specified file for the given tag. + * @return Returns date if exists, otherwise `nil`. + */ +- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag; + +/** + * Saves the date for the specified tag in the specified file. + * @return YES on success, NO otherwise. + */ +- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULKeychainStorage.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULKeychainStorage.h new file mode 100644 index 00000000..dc01a836 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULKeychainStorage.h @@ -0,0 +1,79 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@class FBLPromise<ValueType>; + +NS_ASSUME_NONNULL_BEGIN + +/// The class provides a convenient abstraction on top of the iOS Keychain API to save data. +@interface GULKeychainStorage : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** Initializes the keychain storage with Keychain Service name. + * @param service A Keychain Service name that will be used to store and retrieve objects. See also + * `kSecAttrService`. + */ +- (instancetype)initWithService:(NSString *)service; + +/** + * Get an object by key. + * @param key The key. + * @param objectClass The expected object class required by `NSSecureCoding`. + * @param accessGroup The Keychain Access Group. + * + * @return Returns a promise. It is resolved with an object stored by key if exists. It is resolved + * with `nil` when the object not found. It fails on a Keychain error. + */ +- (FBLPromise<id<NSSecureCoding>> *)getObjectForKey:(NSString *)key + objectClass:(Class)objectClass + accessGroup:(nullable NSString *)accessGroup; + +/** + * Saves the given object by the given key. + * @param object The object to store. + * @param key The key to store the object. If there is an existing object by the key, it will be + * overridden. + * @param accessGroup The Keychain Access Group. + * + * @return Returns which is resolved with `[NSNull null]` on success. + */ +- (FBLPromise<NSNull *> *)setObject:(id<NSSecureCoding>)object + forKey:(NSString *)key + accessGroup:(nullable NSString *)accessGroup; + +/** + * Removes the object by the given key. + * @param key The key to store the object. If there is an existing object by the key, it will be + * overridden. + * @param accessGroup The Keychain Access Group. + * + * @return Returns which is resolved with `[NSNull null]` on success. + */ +- (FBLPromise<NSNull *> *)removeObjectForKey:(NSString *)key + accessGroup:(nullable NSString *)accessGroup; + +#if TARGET_OS_OSX +/// If not `nil`, then only this keychain will be used to save and read data (see +/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests. +@property(nonatomic, nullable) SecKeychainRef keychainRef; +#endif // TARGET_OSX + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULKeychainUtils.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULKeychainUtils.h new file mode 100644 index 00000000..de4bef2f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULKeychainUtils.h @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString *const kGULKeychainUtilsErrorDomain; + +/// Helper functions to access Keychain. +@interface GULKeychainUtils : NSObject + +/** Fetches a keychain item data matching to the provided query. + * @param query A dictionary with Keychain query parameters. See docs for `SecItemCopyMatching` for + * details. + * @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be + * assigned with an error if there is. + * @returns Data for the first Keychain Item matching the provided query or `nil` if there is not + * such an item (`outError` will be `nil` in this case) or an error occurred. + */ ++ (nullable NSData *)getItemWithQuery:(NSDictionary *)query + error:(NSError *_Nullable *_Nullable)outError; + +/** Stores data to a Keychain Item matching to the provided query. An existing Keychain Item + * matching the query parameters will be updated or a new will be created. + * @param item A Keychain Item data to store. + * @param query A dictionary with Keychain query parameters. See docs for `SecItemAdd` and + * `SecItemUpdate` for details. + * @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be + * assigned with an error if there is. + * @returns `YES` when data was successfully stored, `NO` otherwise. + */ ++ (BOOL)setItem:(NSData *)item + withQuery:(NSDictionary *)query + error:(NSError *_Nullable *_Nullable)outError; + +/** Removes a Keychain Item matching to the provided query. + * @param query A dictionary with Keychain query parameters. See docs for `SecItemDelete` for + * details. + * @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be + * assigned with an error if there is. + * @returns `YES` if the item was removed successfully or doesn't exist, `NO` otherwise. + */ ++ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULSecureCoding.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULSecureCoding.h new file mode 100644 index 00000000..8484b395 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Environment/Private/GULSecureCoding.h @@ -0,0 +1,36 @@ +// Copyright 2019 Google +// +// 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. + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** The class wraps `NSKeyedArchiver` and `NSKeyedUnarchiver` API to provide a unified secure coding + * methods for iOS versions before and after 11. + */ +@interface GULSecureCoding : NSObject + ++ (nullable id)unarchivedObjectOfClasses:(NSSet<Class> *)classes + fromData:(NSData *)data + error:(NSError **)outError; + ++ (nullable id)unarchivedObjectOfClass:(Class)class + fromData:(NSData *)data + error:(NSError **)outError; + ++ (nullable NSData *)archivedDataWithRootObject:(id<NSCoding>)object error:(NSError **)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Reachability/Private/GULReachabilityChecker.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Reachability/Private/GULReachabilityChecker.h new file mode 100644 index 00000000..0c70c055 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Reachability/Private/GULReachabilityChecker.h @@ -0,0 +1,79 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> +#if !TARGET_OS_WATCH +#import <SystemConfiguration/SystemConfiguration.h> +#endif + +/// Reachability Status +typedef enum { + kGULReachabilityUnknown, ///< Have not yet checked or been notified whether host is reachable. + kGULReachabilityNotReachable, ///< Host is not reachable. + kGULReachabilityViaWifi, ///< Host is reachable via Wifi. + kGULReachabilityViaCellular, ///< Host is reachable via cellular. +} GULReachabilityStatus; + +const NSString *GULReachabilityStatusString(GULReachabilityStatus status); + +@class GULReachabilityChecker; + +/// Google Analytics iOS Reachability Checker. +@protocol GULReachabilityDelegate +@required +/// Called when network status has changed. +- (void)reachability:(GULReachabilityChecker *)reachability + statusChanged:(GULReachabilityStatus)status; +@end + +/// Google Analytics iOS Network Status Checker. +@interface GULReachabilityChecker : NSObject + +/// The last known reachability status, or GULReachabilityStatusUnknown if the +/// checker is not active. +@property(nonatomic, readonly) GULReachabilityStatus reachabilityStatus; +/// The host to which reachability status is to be checked. +@property(nonatomic, copy, readonly) NSString *host; +/// The delegate to be notified of reachability status changes. +@property(nonatomic, weak) id<GULReachabilityDelegate> reachabilityDelegate; +/// `YES` if the reachability checker is active, `NO` otherwise. +@property(nonatomic, readonly) BOOL isActive; + +/// Initialize the reachability checker. Note that you must call start to begin checking for and +/// receiving notifications about network status changes. +/// +/// @param reachabilityDelegate The delegate to be notified when reachability status to host +/// changes. +/// +/// @param host The name of the host. +/// +- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate + withHost:(NSString *)host; + +- (instancetype)init NS_UNAVAILABLE; + +/// Start checking for reachability to the specified host. This has no effect if the status +/// checker is already checking for connectivity. +/// +/// @return `YES` if initiating status checking was successful or the status checking has already +/// been initiated, `NO` otherwise. +- (BOOL)start; + +/// Stop checking for reachability to the specified host. This has no effect if the status +/// checker is not checking for connectivity. +- (void)stop; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h new file mode 100644 index 00000000..373e0af4 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/Reachability/Private/GULReachabilityMessageCode.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum. +typedef NS_ENUM(NSInteger, GULReachabilityMessageCode) { + // GULReachabilityChecker.m + kGULReachabilityMessageCode000 = 902000, // I-NET902000 + kGULReachabilityMessageCode001 = 902001, // I-NET902001 + kGULReachabilityMessageCode002 = 902002, // I-NET902002 + kGULReachabilityMessageCode003 = 902003, // I-NET902003 + kGULReachabilityMessageCode004 = 902004, // I-NET902004 + kGULReachabilityMessageCode005 = 902005, // I-NET902005 + kGULReachabilityMessageCode006 = 902006, // I-NET902006 +}; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h new file mode 100644 index 00000000..0d047818 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h @@ -0,0 +1,110 @@ +// Copyright 2018 Google +// +// 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. + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/// A thread-safe user defaults that uses C functions from CFPreferences.h instead of +/// `NSUserDefaults`. This is to avoid sending an `NSNotification` when it's changed from a +/// background thread to avoid crashing. // TODO: Insert radar number here. +@interface GULUserDefaults : NSObject + +/// A shared user defaults similar to +[NSUserDefaults standardUserDefaults] and accesses the same +/// data of the standardUserDefaults. ++ (GULUserDefaults *)standardUserDefaults; + +/// Initializes preferences with a suite name that is the same with the NSUserDefaults' suite name. +/// Both of CFPreferences and NSUserDefaults share the same plist file so their data will exactly +/// the same. +/// +/// @param suiteName The name of the suite of the user defaults. +- (instancetype)initWithSuiteName:(nullable NSString *)suiteName; + +#pragma mark - Getters + +/// Searches the receiver's search list for a default with the key 'defaultName' and return it. If +/// another process has changed defaults in the search list, NSUserDefaults will automatically +/// update to the latest values. If the key in question has been marked as ubiquitous via a Defaults +/// Configuration File, the latest value may not be immediately available, and the registered value +/// will be returned instead. +- (nullable id)objectForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray. +- (nullable NSArray *)arrayForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will return nil if the value +/// is not an NSDictionary. +- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will convert NSNumber values to their NSString +/// representation. If a non-string non-number value is found, nil will be returned. +- (nullable NSString *)stringForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it converts the returned value to an NSInteger. If the +/// value is an NSNumber, the result of -integerValue will be returned. If the value is an NSString, +/// it will be converted to NSInteger if possible. If the value is a boolean, it will be converted +/// to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0 +/// will be returned. +- (NSInteger)integerForKey:(NSString *)defaultName; + +/// Similar to -integerForKey:, except that it returns a float, and boolean values will not be +/// converted. +- (float)floatForKey:(NSString *)defaultName; + +/// Similar to -integerForKey:, except that it returns a double, and boolean values will not be +/// converted. +- (double)doubleForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it converts the returned value to a BOOL. If the value +/// is an NSNumber, NO will be returned if the value is 0, YES otherwise. If the value is an +/// NSString, values of "YES" or "1" will return YES, and values of "NO", "0", or any other string +/// will return NO. If the value is absent or can't be converted to a BOOL, NO will be returned. +- (BOOL)boolForKey:(NSString *)defaultName; + +#pragma mark - Setters + +/// Immediately stores a value (or removes the value if `nil` is passed as the value) for the +/// provided key in the search list entry for the receiver's suite name in the current user and any +/// host, then asynchronously stores the value persistently, where it is made available to other +/// processes. +- (void)setObject:(nullable id)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a float to an NSNumber. +- (void)setFloat:(float)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a double to an +/// NSNumber. +- (void)setDouble:(double)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from an NSInteger to an +/// NSNumber. +- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a BOOL to an NSNumber. +- (void)setBool:(BOOL)value forKey:(NSString *)defaultName; + +#pragma mark - Removing Defaults + +/// Equivalent to -[... setObject:nil forKey:defaultName] +- (void)removeObjectForKey:(NSString *)defaultName; + +#pragma mark - Save data + +/// Blocks the calling thread until all in-progress set operations have completed. +- (void)synchronize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRAnalyticsInterop.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRAnalyticsInterop.h new file mode 100644 index 00000000..6581b536 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRAnalyticsInterop.h @@ -0,0 +1,66 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +@protocol FIRAnalyticsInteropListener; + +NS_ASSUME_NONNULL_BEGIN + +/// Block typedef callback parameter to getUserPropertiesWithCallback:. +typedef void (^FIRAInteropUserPropertiesCallback)(NSDictionary<NSString *, id> *userProperties); + +/// Connector for bridging communication between Firebase SDKs and FirebaseAnalytics API. +@protocol FIRAnalyticsInterop + +/// Sets user property when trigger event is logged. This API is only available in the SDK. +- (void)setConditionalUserProperty:(NSDictionary<NSString *, id> *)conditionalUserProperty; + +/// Clears user property if set. +- (void)clearConditionalUserProperty:(NSString *)userPropertyName + forOrigin:(NSString *)origin + clearEventName:(NSString *)clearEventName + clearEventParameters:(NSDictionary<NSString *, NSString *> *)clearEventParameters; + +/// Returns currently set user properties. +- (NSArray<NSDictionary<NSString *, NSString *> *> *)conditionalUserProperties:(NSString *)origin + propertyNamePrefix: + (NSString *)propertyNamePrefix; + +/// Returns the maximum number of user properties. +- (NSInteger)maxUserProperties:(NSString *)origin; + +/// Returns the user properties to a callback function. +- (void)getUserPropertiesWithCallback:(FIRAInteropUserPropertiesCallback)callback; + +/// Logs events. +- (void)logEventWithOrigin:(NSString *)origin + name:(NSString *)name + parameters:(nullable NSDictionary<NSString *, id> *)parameters; + +/// Sets user property. +- (void)setUserPropertyWithOrigin:(NSString *)origin name:(NSString *)name value:(id)value; + +/// Registers an Analytics listener for the given origin. +- (void)registerAnalyticsListener:(id<FIRAnalyticsInteropListener>)listener + withOrigin:(NSString *)origin; + +/// Unregisters an Analytics listener for the given origin. +- (void)unregisterAnalyticsListenerWithOrigin:(NSString *)origin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRAnalyticsInteropListener.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRAnalyticsInteropListener.h new file mode 100644 index 00000000..45cde550 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRAnalyticsInteropListener.h @@ -0,0 +1,24 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +/// Handles events and messages from Analytics. +@protocol FIRAnalyticsInteropListener <NSObject> + +/// Triggers when an Analytics event happens for the registered origin with +/// `FIRAnalyticsInterop`s `registerAnalyticsListener:withOrigin:`. +- (void)messageTriggered:(NSString *)name parameters:(NSDictionary *)parameters; + +@end
\ No newline at end of file diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRInteropEventNames.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRInteropEventNames.h new file mode 100644 index 00000000..efc54ab2 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRInteropEventNames.h @@ -0,0 +1,28 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/// @file FIRInteropEventNames.h + +#import <Foundation/Foundation.h> + +/// Notification open event name. +static NSString *const kFIRIEventNotificationOpen = @"_no"; + +/// Notification foreground event name. +static NSString *const kFIRIEventNotificationForeground = @"_nf"; + +/// Campaign event name. +static NSString *const kFIRIEventFirebaseCampaign = @"_cmp"; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRInteropParameterNames.h b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRInteropParameterNames.h new file mode 100644 index 00000000..ae440bec --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/Interop/Analytics/Public/FIRInteropParameterNames.h @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import <Foundation/Foundation.h> + +/// @file FIRInteropParameterNames.h +/// +/// Predefined event parameter names used by Firebase. This file is a subset of the +/// FirebaseAnalytics FIRParameterNames.h public header. +/// +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (NSString). +/// <pre> +/// NSDictionary *params = @{ +/// kFIRParameterSource : @"InMobi", +/// // ... +/// }; +/// </pre> +static NSString *const kFIRIParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (NSString). +/// <pre> +/// NSDictionary *params = @{ +/// kFIRParameterMedium : @"email", +/// // ... +/// }; +/// </pre> +static NSString *const kFIRIParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (NSString). +/// <pre> +/// NSDictionary *params = @{ +/// kFIRParameterCampaign : @"winter_promotion", +/// // ... +/// }; +/// </pre> +static NSString *const kFIRIParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Message identifier. +static NSString *const kFIRIParameterMessageIdentifier = @"_nmid"; + +/// Message name. +static NSString *const kFIRIParameterMessageName = @"_nmn"; + +/// Message send time. +static NSString *const kFIRIParameterMessageTime = @"_nmt"; + +/// Message device time. +static NSString *const kFIRIParameterMessageDeviceTime = @"_ndt"; + +/// Topic message. +static NSString *const kFIRIParameterTopic = @"_nt"; + +/// Stores the message_id of the last notification opened by the app. +static NSString *const kFIRIUserPropertyLastNotification = @"_ln"; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/LICENSE b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/LICENSE new file mode 100644 index 00000000..fcce5066 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Firebase, 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. diff --git a/StoneIsland/platforms/ios/Pods/FirebaseMessaging/README.md b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/README.md new file mode 100644 index 00000000..1d9f0f67 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseMessaging/README.md @@ -0,0 +1,298 @@ +[](https://cocoapods.org/pods/Firebase) +[](https://cocoapods.org/pods/Firebase) +[](https://cocoapods.org/pods/Firebase) + +[![Actions Status][gh-abtesting-badge]][gh-actions] +[![Actions Status][gh-auth-badge]][gh-actions] +[![Actions Status][gh-core-badge]][gh-actions] +[![Actions Status][gh-crashlytics-badge]][gh-actions] +[![Actions Status][gh-database-badge]][gh-actions] +[![Actions Status][gh-datatransport-badge]][gh-actions] +[![Actions Status][gh-dynamiclinks-badge]][gh-actions] +[![Actions Status][gh-firebasepod-badge]][gh-actions] +[![Actions Status][gh-firestore-badge]][gh-actions] +[![Actions Status][gh-functions-badge]][gh-actions] +[![Actions Status][gh-inappmessaging-badge]][gh-actions] +[![Actions Status][gh-interop-badge]][gh-actions] +[![Actions Status][gh-messaging-badge]][gh-actions] +[![Actions Status][gh-remoteconfig-badge]][gh-actions] +[![Actions Status][gh-storage-badge]][gh-actions] +[![Actions Status][gh-symbolcollision-badge]][gh-actions] +[![Actions Status][gh-zip-badge]][gh-actions] +[](https://travis-ci.org/firebase/firebase-ios-sdk) + +# Firebase Apple Open Source Development + +This repository contains all Apple platform Firebase SDK source except FirebaseAnalytics, +FirebasePerformance, and FirebaseML. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +### Using Firebase from a Framework or a library + +[Using Firebase from a Framework or a library](docs/firebase_in_libraries.md) + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + + * Xcode 10.3 (or later) + * CocoaPods 1.7.2 (or later) + * [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self contained Xcode project. See +[Firestore/README.md](Firestore/README.md). + +### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +### Adding a New Firebase Pod + +See [AddNewPod.md](AddNewPod.md). + +### Managing Headers and Imports + +See [HeadersImports.md](HeadersImports.md). + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh) +before creating a PR. + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`: + +``` +brew install clang-format +brew install swiftformat +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +#### Viewing Code Coverage (Deprecated) + +First, make sure that [xcov](https://github.com/nakiostudio/xcov) is installed with `gem install xcov`. + +After running the `AllUnitTests_iOS` scheme in Xcode, execute +`xcov --workspace Firebase.xcworkspace --scheme AllUnitTests_iOS --output_directory xcov_output` +at Example/ in the terminal. This will aggregate the coverage, and you can run `open xcov_output/index.html` to see the results. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid GoogleServices-Info.plist and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](FirebaseStorage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### tvOS, macOS, watchOS and Catalyst +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and work on +tvOS, macOS, watchOS and Catalyst. + +For tvOS, checkout the [Sample](Example/tvOSSample). +For watchOS, currently only Messaging and Storage (and their dependencies) have limited support. Checkout the +[Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that macOS, tvOS, watchOS and Catalyst are not officially supported by Firebase, and this +repository is actively developed primarily for iOS. While we can catch basic unit test issues with +Travis, there may be some changes where the SDK no longer works as expected on macOS, tvOS or watchOS. If you +encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the app +has communicated with our servers". This relies on Analytics and will not work on macOS/tvOS/watchOS/Catalyst. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +To install, add a subset of the following to the Podfile: + +``` +pod 'Firebase/ABTesting' # No watchOS support yet +pod 'Firebase/Auth' # No watchOS support yet +pod 'Firebase/Crashlytics' # No watchOS support yet +pod 'Firebase/Database' # No watchOS support yet +pod 'Firebase/Firestore' # No watchOS support yet +pod 'Firebase/Functions' # No watchOS support yet +pod 'Firebase/Messaging' +pod 'Firebase/RemoteConfig' # No watchOS support yet +pod 'Firebase/Storage' +``` + +#### Additional Catalyst Notes + +* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability` +to Build Settings. +* FirebaseFirestore requires signing the +[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). + +[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions +[gh-abtesting-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/abtesting/badge.svg +[gh-auth-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/auth/badge.svg +[gh-core-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core/badge.svg +[gh-crashlytics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/crashlytics/badge.svg +[gh-database-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/database/badge.svg +[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg +[gh-dynamiclinks-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/dynamiclinks/badge.svg +[gh-firebasepod-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firebasepod/badge.svg +[gh-firestore-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firestore/badge.svg +[gh-functions-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/functions/badge.svg +[gh-inappmessaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/inappmessaging/badge.svg +[gh-interop-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/interop/badge.svg +[gh-messaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/messaging/badge.svg +[gh-remoteconfig-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/remoteconfig/badge.svg +[gh-storage-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/storage/badge.svg +[gh-symbolcollision-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/symbolcollision/badge.svg +[gh-zip-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/zip/badge.svg |
