Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2019 Google
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#import "Crashlytics/Crashlytics/Models/FIRCLSInstallIdentifierModel.h"
16
 
17
#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h"
18
 
19
#import "Crashlytics/Crashlytics/FIRCLSUserDefaults/FIRCLSUserDefaults.h"
20
#import "Crashlytics/Crashlytics/Helpers/FIRCLSLogger.h"
21
#import "Crashlytics/Shared/FIRCLSByteUtility.h"
22
#import "Crashlytics/Shared/FIRCLSUUID.h"
23
 
24
static NSString *const FIRCLSInstallationUUIDKey = @"com.crashlytics.iuuid";
25
static NSString *const FIRCLSInstallationIIDHashKey = @"com.crashlytics.install.iid";
26
 
27
// Legacy key that is automatically removed
28
static NSString *const FIRCLSInstallationADIDKey = @"com.crashlytics.install.adid";
29
 
30
static unsigned long long FIRCLSInstallationsWaitTime = 10 * NSEC_PER_SEC;
31
 
32
@interface FIRCLSInstallIdentifierModel ()
33
 
34
@property(nonatomic, copy) NSString *installID;
35
 
36
@property(nonatomic, readonly) FIRInstallations *installations;
37
 
38
@end
39
 
40
@implementation FIRCLSInstallIdentifierModel
41
 
42
// This needs to be synthesized so we can set without using the setter in the constructor and
43
// overridden setters and getters
44
@synthesize installID = _installID;
45
 
46
- (instancetype)initWithInstallations:(FIRInstallations *)installations {
47
  self = [super init];
48
  if (!self) {
49
    return nil;
50
  }
51
 
52
  // capture the install ID information
53
  _installID = [self readInstallationUUID].copy;
54
  _installations = installations;
55
 
56
  if (!_installID) {
57
    FIRCLSDebugLog(@"Generating Install ID");
58
    _installID = [self generateInstallationUUID].copy;
59
 
60
    FIRCLSUserDefaults *defaults = [FIRCLSUserDefaults standardUserDefaults];
61
    [defaults synchronize];
62
  }
63
 
64
  return self;
65
}
66
 
67
- (NSString *)installID {
68
  @synchronized(self) {
69
    return _installID;
70
  }
71
}
72
 
73
- (void)setInstallID:(NSString *)installID {
74
  @synchronized(self) {
75
    _installID = installID;
76
  }
77
}
78
 
79
/**
80
 * Reads installation UUID stored in persistent storage.
81
 * If the installation UUID is stored in legacy key, migrates it over to the new key.
82
 */
83
- (NSString *)readInstallationUUID {
84
  return [[FIRCLSUserDefaults standardUserDefaults] objectForKey:FIRCLSInstallationUUIDKey];
85
}
86
 
87
/**
88
 * Generates a new UUID and saves it in persistent storage.
89
 * Does not sychronize the user defaults (to allow optimized
90
 * batching of user default synchronizing)
91
 */
92
- (NSString *)generateInstallationUUID {
93
  NSString *UUID = FIRCLSGenerateUUID();
94
  FIRCLSUserDefaults *userDefaults = [FIRCLSUserDefaults standardUserDefaults];
95
  [userDefaults setObject:UUID forKey:FIRCLSInstallationUUIDKey];
96
  return UUID;
97
}
98
 
99
#pragma mark Privacy Shield
100
 
101
- (BOOL)regenerateInstallIDIfNeeded {
102
  BOOL __block didRotate = false;
103
 
104
  dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
105
 
106
  // This runs Completion async, so wait a reasonable amount of time for it to finish.
107
  [self.installations
108
      installationIDWithCompletion:^(NSString *_Nullable currentIID, NSError *_Nullable error) {
109
        didRotate = [self rotateCrashlyticsInstallUUIDWithIID:currentIID error:error];
110
 
111
        if (didRotate) {
112
          FIRCLSInfoLog(@"Rotated Crashlytics Install UUID because Firebase Install ID changed");
113
        }
114
        dispatch_semaphore_signal(semaphore);
115
      }];
116
 
117
  intptr_t result = dispatch_semaphore_wait(
118
      semaphore, dispatch_time(DISPATCH_TIME_NOW, FIRCLSInstallationsWaitTime));
119
  if (result != 0) {
120
    FIRCLSErrorLog(@"Crashlytics timed out while checking for Firebase Installation ID");
121
  }
122
 
123
  return didRotate;
124
}
125
 
126
- (BOOL)rotateCrashlyticsInstallUUIDWithIID:(NSString *_Nullable)currentIID
127
                                      error:(NSError *_Nullable)error {
128
  BOOL didRotate = NO;
129
 
130
  FIRCLSUserDefaults *defaults = [FIRCLSUserDefaults standardUserDefaults];
131
 
132
  // Remove the legacy ID
133
  NSString *adID = [defaults objectForKey:FIRCLSInstallationADIDKey];
134
  if (adID.length != 0) {
135
    [defaults removeObjectForKey:FIRCLSInstallationADIDKey];
136
    [defaults synchronize];
137
  }
138
 
139
  if (error != nil) {
140
    FIRCLSErrorLog(@"Failed to get Firebase Instance ID: %@", error);
141
    return didRotate;
142
  }
143
 
144
  if (currentIID.length == 0) {
145
    FIRCLSErrorLog(@"Firebase Instance ID was empty when checked for changes");
146
    return didRotate;
147
  }
148
 
149
  NSString *currentIIDHash =
150
      FIRCLS256HashNSData([currentIID dataUsingEncoding:NSUTF8StringEncoding]);
151
  NSString *lastIIDHash = [defaults objectForKey:FIRCLSInstallationIIDHashKey];
152
 
153
  // If the IDs are the same, we never regenerate
154
  if ([lastIIDHash isEqualToString:currentIIDHash]) {
155
    return didRotate;
156
  }
157
 
158
  // If we had an FIID saved, we know it's not an upgrade scenario, so we can regenerate
159
  if (lastIIDHash.length != 0) {
160
    FIRCLSDebugLog(@"Regenerating Install ID");
161
    self.installID = [self generateInstallationUUID].copy;
162
    didRotate = YES;
163
  }
164
 
165
  // Write the new FIID to UserDefaults
166
  [defaults setObject:currentIIDHash forKey:FIRCLSInstallationIIDHashKey];
167
  [defaults synchronize];
168
 
169
  return didRotate;
170
}
171
 
172
@end