/core/externals/update-engine/Core/KSPrefetchAction.m

http://macfuse.googlecode.com/ · Objective C · 107 lines · 63 code · 17 blank · 27 comment · 9 complexity · 93c5192e31fab771be1f2edd6151de4a MD5 · raw file

  1. // Copyright 2008 Google Inc.
  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. #import "KSPrefetchAction.h"
  15. #import "KSUpdateEngine.h"
  16. #import "KSActionPipe.h"
  17. #import "KSDownloadAction.h"
  18. #import "KSActionProcessor.h"
  19. #import "KSUpdateInfo.h"
  20. @implementation KSPrefetchAction
  21. + (id)actionWithEngine:(KSUpdateEngine *)engine {
  22. return [[[self alloc] initWithEngine:engine] autorelease];
  23. }
  24. - (id)init {
  25. return [self initWithEngine:nil];
  26. }
  27. - (id)initWithEngine:(KSUpdateEngine *)engine {
  28. if ((self = [super init])) {
  29. engine_ = [engine retain];
  30. if (engine_ == nil) {
  31. [self release];
  32. return nil;
  33. }
  34. }
  35. return self;
  36. }
  37. - (void)dealloc {
  38. [engine_ release];
  39. [super dealloc];
  40. }
  41. - (void)performAction {
  42. NSArray *availableUpdates = [[self inPipe] contents];
  43. // Our output must always be the same as our input, so we'll set that up now
  44. [[self outPipe] setContents:availableUpdates];
  45. if (availableUpdates == nil) {
  46. GTMLoggerInfo(@"no updates available.");
  47. [[self processor] finishedProcessing:self successfully:YES];
  48. return;
  49. }
  50. _GTMDevAssert(engine_ != nil, @"engine_ must not be nil");
  51. // Send the available updates to the delegate to figure out which ones should
  52. // be prefetched. The delegate will return an array of product dictionaries
  53. // that we should prefetch.
  54. //
  55. // Security note:
  56. // The delegate is untrusted so we can't trust the product dictionaries that
  57. // we get back. So, we use the returned product dictionaries to filter our
  58. // original list of |availableUpdates| to the ones the delegate requested.
  59. NSArray *updatesToPrefetch = [engine_ action:self
  60. shouldPrefetchProducts:availableUpdates];
  61. // Filter our list of available updates to only those that the delegate told
  62. // us to prefetch.
  63. NSArray *prefetches =
  64. [availableUpdates filteredArrayUsingPredicate:
  65. [NSPredicate predicateWithFormat:
  66. @"SELF IN %@", updatesToPrefetch]];
  67. // Use -description because it prints nicer than the way CF would format it
  68. GTMLoggerInfo(@"prefetches=%@", [prefetches description]);
  69. // Convert each dictionary in |prefetches| into a KSDownloadAction and
  70. // enqueue it on our subProcessor
  71. NSEnumerator *prefetchEnumerator = [prefetches objectEnumerator];
  72. KSUpdateInfo *info = nil;
  73. while ((info = [prefetchEnumerator nextObject])) {
  74. NSString *dmgName =
  75. [[info productID] stringByAppendingPathExtension:@"dmg"];
  76. KSAction *action =
  77. [KSDownloadAction actionWithURL:[info codebaseURL]
  78. size:[[info codeSize] intValue]
  79. hash:[info codeHash]
  80. name:dmgName];
  81. [[self subProcessor] enqueueAction:action];
  82. }
  83. if ([[[self subProcessor] actions] count] == 0) {
  84. GTMLoggerInfo(@"No prefetch downloads created.");
  85. [[self processor] finishedProcessing:self successfully:YES];
  86. return;
  87. }
  88. [[self subProcessor] startProcessing];
  89. }
  90. @end