Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(963)

Side by Side Diff: components/update_client/updater_state_mac.mm

Issue 2862723002: Add updater state for Mac. (Closed)
Patch Set: Scoped pointers for NSObject instances; removed a memory leak when reading different type. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import <Foundation/Foundation.h>
6 #import <OpenDirectory/OpenDirectory.h>
7
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/mac/foundation_util.h"
11 #include "base/mac/scoped_nsautorelease_pool.h"
12 #include "base/mac/scoped_nsobject.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "base/version.h"
15 #include "components/update_client/updater_state.h"
16
17 namespace update_client {
18
19 namespace {
20
21 const base::FilePath::CharType kKeystonePlist[] = FILE_PATH_LITERAL(
22 "Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
23 "Contents/Info.plist");
24
25 // Gets a value from the updater settings. Returns a retained object.
26 // T should be a toll-free Foundation framework type. See Apple's
27 // documentation for toll-free bridging.
28 template<class T>
29 base::scoped_nsobject<T> GetUpdaterSettingsValue(NSString* value_name) {
30 CFStringRef app_id = CFSTR("com.google.Keystone.Agent");
31 CFPropertyListRef plist =
Robert Sesek 2017/05/08 17:14:13 Switch this to a base::ScopedCFTypeRef and then yo
Boris Vidolov 2017/05/08 18:18:07 Thanks, Robert. One more scoped pointer type that
32 CFPreferencesCopyAppValue(base::mac::NSToCFCast(value_name), app_id);
33 if (!plist) return base::scoped_nsobject<T>(nil);
34 T* value = base::mac::ObjCCastStrict<T>(static_cast<id>(plist));
35 if (!value) {
36 // Some other type, do not leak:
37 CFRelease(value);
38 return base::scoped_nsobject<T>(nil);
39 }
40 return base::scoped_nsobject<T>(value);
41 }
42
43 base::Time GetUpdaterSettingsTime(NSString* value_name) {
44 base::scoped_nsobject<NSDate> date =
45 GetUpdaterSettingsValue<NSDate>(value_name);
46 base::Time result =
47 base::Time::FromCFAbsoluteTime([date timeIntervalSinceReferenceDate]);
48
49 return result;
50 }
51
52 base::Version GetVersionFromPlist(const base::FilePath& info_plist) {
53 base::mac::ScopedNSAutoreleasePool scoped_pool;
54 NSData* data =
55 [NSData dataWithContentsOfFile:
56 base::mac::FilePathToNSString(info_plist)];
57 if ([data length] == 0) {
58 return base::Version();
59 }
60 NSDictionary* all_keys = base::mac::ObjCCastStrict<NSDictionary>(
61 [NSPropertyListSerialization propertyListWithData:data
62 options:NSPropertyListImmutable
63 format:nil
64 error:nil]);
65 if (all_keys == nil) {
66 return base::Version();
67 }
68 CFStringRef version =
69 base::mac::GetValueFromDictionary<CFStringRef>(
70 base::mac::NSToCFCast(all_keys),
71 kCFBundleVersionKey);
72 if (version == NULL) {
73 return base::Version();
74 }
75 return base::Version(base::SysCFStringRefToUTF8(version));
76 }
77
78 } // namespace
79
80 std::string UpdaterState::GetUpdaterName() {
81 return std::string("Keystone");
82 }
83
84 base::Version UpdaterState::GetUpdaterVersion(bool /*is_machine*/) {
85 // System Keystone trumps user one, so check this one first
86 base::FilePath local_library;
87 bool success = base::mac::GetLocalDirectory(NSLibraryDirectory,
88 &local_library);
89 DCHECK(success);
90 base::FilePath system_bundle_plist = local_library.Append(kKeystonePlist);
91 base::Version system_keystone = GetVersionFromPlist(system_bundle_plist);
92 if (system_keystone.IsValid()) {
93 return system_keystone;
94 }
95
96 base::FilePath user_bundle_plist =
97 base::mac::GetUserLibraryPath().Append(kKeystonePlist);
98 return GetVersionFromPlist(user_bundle_plist);
99 }
100
101 base::Time UpdaterState::GetUpdaterLastStartedAU(bool /*is_machine*/) {
102 return GetUpdaterSettingsTime(@"lastCheckStartDate");
103 }
104
105 base::Time UpdaterState::GetUpdaterLastChecked(bool /*is_machine*/) {
106 return GetUpdaterSettingsTime(@"lastServerCheckDate");
107 }
108
109 bool UpdaterState::IsAutoupdateCheckEnabled() {
110 // Auto-update check period override (in seconds).
111 // Applies only to older versions of Keystone.
112 base::scoped_nsobject<NSNumber> timeInterval =
113 GetUpdaterSettingsValue<NSNumber>(@"checkInterval");
114 if (!timeInterval.get()) return true;
115 int value = [timeInterval intValue];
116
117 return 0 < value && value < (24 * 60 * 60);
118 }
119
120 int UpdaterState::GetUpdatePolicy() {
121 return -1; // Keystone does not support update policies.
122 }
123
124 bool UpdaterState::IsJoinedToDomain() {
125 base::mac::ScopedNSAutoreleasePool scoped_pool;
126
127 ODSession* session = [ODSession defaultSession];
128 if (session == nil) {
129 DLOG(WARNING) << "ODSession defult session is nil.";
130 return false;
131 }
132
133 NSError* error = nil;
134 ODNode* node = [ODNode nodeWithSession:session
135 type:kODNodeTypeAuthentication
136 error:&error];
137 if (node == nil) {
138 DLOG(WARNING) << "ODSession cannot obtain the authentication node: "
139 << base::mac::NSToCFCast(error);
140 return false;
141 }
142
143 ODQuery* query = [ODQuery queryWithNode:node
144 forRecordTypes:kODRecordTypeUsers
145 attribute:kODAttributeTypeRecordName
146 matchType:kODMatchEqualTo
147 queryValues:NSUserName()
148 returnAttributes:kODAttributeTypeAllAttributes
149 maximumResults:0
150 error:&error];
151 if (query == nil) {
152 DLOG(WARNING) << "ODSession cannot create user query: "
153 << base::mac::NSToCFCast(error);
154 return false;
155 }
156
157 NSArray* results = [query resultsAllowingPartial:NO error:&error];
158 if (!results) {
159 DLOG(WARNING) << "ODSession cannot obtain current user node: "
160 << base::mac::NSToCFCast(error);
161 return false;
162 }
163 if (results.count != 1) {
164 DLOG(WARNING) << @"ODSession unexpected number of nodes: "
165 << results.count;
166 }
167 for (id element in results) {
168 ODRecord* record = base::mac::ObjCCastStrict<ODRecord>(element);
169 NSArray* attributes =
170 [record valuesForAttribute:kODAttributeTypeMetaRecordName
171 error:NULL];
172 for (id attribute in attributes) {
173 NSString* attribute_value =
174 base::mac::ObjCCastStrict<NSString>(attribute);
175 // Example: "uid=johnsmith,ou=People,dc=chromium,dc=org
176 NSRange dc = [attribute_value rangeOfString:@"(^|,)\\s*dc="
177 options:NSRegularExpressionSearch];
178 if (dc.length > 0) {
179 return true;
180 }
181 }
182 }
183 return false;
184 }
185
186 } // namespace update_client
OLDNEW
« no previous file with comments | « components/update_client/updater_state.cc ('k') | components/update_client/updater_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698