VLCAppDelegate.m 12.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*****************************************************************************
 * VLCAppDelegate.m
 * VLC for iOS
 *****************************************************************************
 * Copyright (c) 2013 VideoLAN. All rights reserved.
 * $Id$
 *
 * Authors: Felix Paul Kühne <fkuehne # videolan.org>
 *          Gleb Pinigin <gpinigin # gmail.com>
 *          Jean-Romain Prévost <jr # 3on.fr>
 *          Luis Fernandes <zipleen # gmail.com>
 *          Carola Nitz <nitz.carola # googlemail.com>
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/
Felix Paul Kühne's avatar
Felix Paul Kühne committed
16
17

#import "VLCAppDelegate.h"
Gleb Pinigin's avatar
Gleb Pinigin committed
18
#import "VLCMediaFileDiscoverer.h"
19
#import "NSString+SupportedMedia.h"
20
#import "UIDevice+SpeedCategory.h"
Felix Paul Kühne's avatar
Felix Paul Kühne committed
21
22

#import "VLCPlaylistViewController.h"
23
#import "VLCMovieViewController.h"
24
#import "PAPasscodeViewController.h"
25
#import "UINavigationController+Theme.h"
26
#import "VLCHTTPUploaderController.h"
27
#import "VLCMenuTableViewController.h"
28

Gleb Pinigin's avatar
Gleb Pinigin committed
29
@interface VLCAppDelegate () <PAPasscodeViewControllerDelegate, VLCMediaFileDiscovererDelegate> {
Gleb Pinigin's avatar
Gleb Pinigin committed
30
    PAPasscodeViewController *_passcodeLockController;
Gleb Pinigin's avatar
Gleb Pinigin committed
31
    VLCDropboxTableViewController *_dropboxTableViewController;
Carola's avatar
Carola committed
32
    VLCGoogleDriveTableViewController *_googleDriveTableViewController;
33
    VLCDownloadViewController *_downloadViewController;
34
    int _idleCounter;
35
    VLCMovieViewController *_movieViewController;
Gleb Pinigin's avatar
Gleb Pinigin committed
36
}
37
38
39
40

@property (nonatomic) BOOL passcodeValidated;

@end
Felix Paul Kühne's avatar
Felix Paul Kühne committed
41
42
43

@implementation VLCAppDelegate

44
45
46
47
+ (void)initialize
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

48
49
50
51
52
    NSNumber *skipLoopFilterDefaultValue;
    int deviceSpeedCategory = [[UIDevice currentDevice] speedCategory];
    if (deviceSpeedCategory < 3)
        skipLoopFilterDefaultValue = kVLCSettingSkipLoopFilterNonKey;
    else
53
        skipLoopFilterDefaultValue = kVLCSettingSkipLoopFilterNonRef;
54

55
    NSDictionary *appDefaults = @{kVLCSettingPasscodeKey : @"", kVLCSettingPasscodeOnKey : @(NO), kVLCSettingContinueAudioInBackgroundKey : @(YES), kVLCSettingStretchAudio : @(NO), kVLCSettingTextEncoding : kVLCSettingTextEncodingDefaultValue, kVLCSettingSkipLoopFilter : skipLoopFilterDefaultValue, kVLCSettingSubtitlesFont : kVLCSettingSubtitlesFontDefaultValue, kVLCSettingSubtitlesFontColor : kVLCSettingSubtitlesFontColorDefaultValue, kVLCSettingSubtitlesFontSize : kVLCSettingSubtitlesFontSizeDefaultValue, kVLCSettingDeinterlace : kVLCSettingDeinterlaceDefaultValue};
56
57
58
59

    [defaults registerDefaults:appDefaults];
}

Felix Paul Kühne's avatar
Felix Paul Kühne committed
60
61
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
62
63
64
    // Init the HTTP Server
    self.uploadController = [[VLCHTTPUploaderController alloc] init];

65
66
67
    // enable crash preventer
    [[MLMediaLibrary sharedMediaLibrary] applicationWillStart];

Felix Paul Kühne's avatar
Felix Paul Kühne committed
68
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
69

70
    _playlistViewController = [[VLCPlaylistViewController alloc] init];
71
72
    UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:_playlistViewController];
    [navCon loadTheme];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
73

74
    _revealController = [[GHRevealViewController alloc] initWithNibName:nil bundle:nil];
75
    _revealController.wantsFullScreenLayout = YES;
76
77
    _menuViewController = [[VLCMenuTableViewController alloc] initWithNibName:nil bundle:nil];
    _revealController.sidebarViewController = _menuViewController;
78
    _revealController.contentViewController = navCon;
79

80
    self.window.rootViewController = self.revealController;
81
82
    // necessary to avoid navbar blinking in VLCOpenNetworkStreamViewController & VLCDownloadViewController
    _revealController.contentViewController.view.backgroundColor = [UIColor colorWithWhite:.122 alpha:1.];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
83
    [self.window makeKeyAndVisible];
84

Gleb Pinigin's avatar
Gleb Pinigin committed
85
86
87
    VLCMediaFileDiscoverer *discoverer = [VLCMediaFileDiscoverer sharedInstance];
    [discoverer addObserver:self];
    [discoverer startDiscovering:[self directoryPath]];
88

89
    [self validatePasscode];
90

Felix Paul Kühne's avatar
Felix Paul Kühne committed
91
92
93
    return YES;
}

94
95
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
96
97
98
99
100
    if ([[DBSession sharedSession] handleOpenURL:url]) {
        [self.dropboxTableViewController updateViewAfterSessionChange];
        return YES;
    }

101
102
    if (_playlistViewController && url != nil) {
        APLog(@"%@ requested %@ to be opened", sourceApplication, url);
103

104
        if (url.isFileURL) {
105
106
107
108
109
110
111
112
113
            NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *directoryPath = searchPaths[0];
            NSURL *destinationURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", directoryPath, url.lastPathComponent]];
            NSError *theError;
            [[NSFileManager defaultManager] moveItemAtURL:url toURL:destinationURL error:&theError];
            if (theError.code != noErr)
                APLog(@"saving the file failed (%i): %@", theError.code, theError.localizedDescription);

            [self updateMediaList];
Luis's avatar
Luis committed
114
        } else {
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
            NSString *receivedUrl = [url absoluteString];
            if ([receivedUrl length] > 6) {
                NSString *verifyVlcUrl = [receivedUrl substringToIndex:6];
                if ([verifyVlcUrl isEqualToString:@"vlc://"]) {
                    NSString *parsedString = [receivedUrl substringFromIndex:6];
                    NSUInteger location = [parsedString rangeOfString:@"//"].location;

                    /* Safari & al mangle vlc://http:// so fix this */
                    if (location != NSNotFound && [parsedString characterAtIndex:location - 1] != 0x3a) { // :
                            parsedString = [NSString stringWithFormat:@"%@://%@", [parsedString substringToIndex:location], [parsedString substringFromIndex:location+2]];
                    } else
                        parsedString = [@"http://" stringByAppendingString:[receivedUrl substringFromIndex:6]];

                    url = [NSURL URLWithString:parsedString];
                }
            }
131
            [self.menuViewController selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
132
            [self openMovieFromURL:url];
Luis's avatar
Luis committed
133
        }
134
135
136
137
138
        return YES;
    }
    return NO;
}

139
140
141
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [[MLMediaLibrary sharedMediaLibrary] applicationWillStart];
142
    [self validatePasscode];
143
144
}

Felix Paul Kühne's avatar
Felix Paul Kühne committed
145
146
- (void)applicationWillResignActive:(UIApplication *)application
{
147
    self.passcodeValidated = NO;
148
    [self validatePasscode];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
149
150
151
152
153
    [[MLMediaLibrary sharedMediaLibrary] applicationWillExit];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
154
    [self validatePasscode];
155
    [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
156
157
158
    [self updateMediaList];
}

159
160
- (void)applicationWillTerminate:(UIApplication *)application
{
161
    self.passcodeValidated = NO;
162
163
164
    [[NSUserDefaults standardUserDefaults] synchronize];
}

Gleb Pinigin's avatar
Gleb Pinigin committed
165
166
167
168
#pragma mark - properties

- (VLCDropboxTableViewController *)dropboxTableViewController
{
Felix Paul Kühne's avatar
Felix Paul Kühne committed
169
    if (_dropboxTableViewController == nil)
170
        _dropboxTableViewController = [[VLCDropboxTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
Gleb Pinigin's avatar
Gleb Pinigin committed
171
172
173
174

    return _dropboxTableViewController;
}

Carola's avatar
Carola committed
175
176
- (VLCGoogleDriveTableViewController *)googleDriveTableViewController
{
Felix Paul Kühne's avatar
Felix Paul Kühne committed
177
    if (_googleDriveTableViewController == nil)
178
        _googleDriveTableViewController = [[VLCGoogleDriveTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
Carola's avatar
Carola committed
179
180
181
182
183

    return _googleDriveTableViewController;
}


184
185
- (VLCDownloadViewController *)downloadViewController
{
Felix Paul Kühne's avatar
Felix Paul Kühne committed
186
    if (_downloadViewController == nil)
187
188
189
190
191
        _downloadViewController = [[VLCDownloadViewController alloc] init];

    return _downloadViewController;
}

Gleb Pinigin's avatar
Gleb Pinigin committed
192
#pragma mark - media discovering
193

Gleb Pinigin's avatar
Gleb Pinigin committed
194
195
196
197
- (void)mediaFileAdded:(NSString *)fileName loading:(BOOL)isLoading {
    if (!isLoading) {
        MLMediaLibrary *sharedLibrary = [MLMediaLibrary sharedMediaLibrary];
        [sharedLibrary addFilePaths:@[fileName]];
198

Gleb Pinigin's avatar
Gleb Pinigin committed
199
200
201
        /* exclude media files from backup (QA1719) */
        NSURL *excludeURL = [NSURL fileURLWithPath:fileName];
        [excludeURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
202

Gleb Pinigin's avatar
Gleb Pinigin committed
203
204
        // TODO Should we update media db after adding new files?
        [sharedLibrary updateMediaDatabase];
205
        [_playlistViewController updateViewContents];
206
207
208
    }
}

Gleb Pinigin's avatar
Gleb Pinigin committed
209
210
211
212
213
- (void)mediaFileDeleted:(NSString *)name {
    [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
    [_playlistViewController updateViewContents];
}

214
215
216
#pragma mark - media list methods

- (NSString *)directoryPath
Felix Paul Kühne's avatar
Felix Paul Kühne committed
217
{
218
#define LOCAL_PLAYBACK_HACK 0
Felix Paul Kühne's avatar
Felix Paul Kühne committed
219
220
221
#if LOCAL_PLAYBACK_HACK && TARGET_IPHONE_SIMULATOR
    NSString *directoryPath = @"/Users/fkuehne/Desktop/VideoLAN docs/Clips/sel/";
#else
222
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
Felix Paul Kühne's avatar
Felix Paul Kühne committed
223
    NSString *directoryPath = searchPaths[0];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
224
#endif
225
226
227
228
229
230
231

    return directoryPath;
}

- (void)updateMediaList
{
    NSString *directoryPath = [self directoryPath];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
232
233
    NSArray *foundFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil];
    NSMutableArray *filePaths = [NSMutableArray arrayWithCapacity:[foundFiles count]];
234
    NSURL *fileURL;
Felix Paul Kühne's avatar
Felix Paul Kühne committed
235
    for (NSString *fileName in foundFiles) {
236
        if ([fileName isSupportedMediaFormat] || [fileName isSupportedAudioMediaFormat]) {
Felix Paul Kühne's avatar
Felix Paul Kühne committed
237
            [filePaths addObject:[directoryPath stringByAppendingPathComponent:fileName]];
238
239

            /* exclude media files from backup (QA1719) */
240
            fileURL = [NSURL fileURLWithPath:[directoryPath stringByAppendingPathComponent:fileName]];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
241
            [fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
242
243
244
        }
    }
    [[MLMediaLibrary sharedMediaLibrary] addFilePaths:filePaths];
245
    [_playlistViewController updateViewContents];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
246
247
}

248
249
250
251
252
253
#pragma mark - pass code validation

- (void)validatePasscode
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *passcode = [defaults objectForKey:kVLCSettingPasscodeKey];
254
    if ([passcode isEqualToString:@""] || ![[defaults objectForKey:kVLCSettingPasscodeOnKey] boolValue]) {
255
256
257
        self.passcodeValidated = YES;
        return;
    }
258

259
    if (!self.passcodeValidated) {
260
261
262
263
        _passcodeLockController = [[PAPasscodeViewController alloc] initForAction:PasscodeActionEnter];
        _passcodeLockController.delegate = self;
        _passcodeLockController.passcode = passcode;
        self.window.rootViewController = _passcodeLockController;
264
265
266
267
268
    }
}

- (void)PAPasscodeViewControllerDidEnterPasscode:(PAPasscodeViewController *)controller
{
269
    // TODO add transition animation, i.e. fade
270
    self.window.rootViewController = self.revealController;
271
272
273
274
275
276
277
}

- (void)PAPasscodeViewController:(PAPasscodeViewController *)controller didFailToEnterPasscode:(NSInteger)attempts
{
    // TODO handle error attempts
}

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
#pragma mark - idle timer preventer
- (void)disableIdleTimer
{
    _idleCounter++;
    if ([UIApplication sharedApplication].idleTimerDisabled == NO)
        [UIApplication sharedApplication].idleTimerDisabled = YES;
}

- (void)activateIdleTimer
{
    _idleCounter--;
    if (_idleCounter < 1)
        [UIApplication sharedApplication].idleTimerDisabled = NO;
}

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#pragma mark - playback view handling

- (void)openMediaFromManagedObject:(NSManagedObject *)mediaObject
{
    if (!_movieViewController)
        _movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];

    if ([mediaObject isKindOfClass:[MLFile class]])
        _movieViewController.mediaItem = (MLFile *)mediaObject;
    else if ([mediaObject isKindOfClass:[MLAlbumTrack class]])
        _movieViewController.mediaItem = [(MLAlbumTrack*)mediaObject files].anyObject;
    else if ([mediaObject isKindOfClass:[MLShowEpisode class]])
        _movieViewController.mediaItem = [(MLShowEpisode*)mediaObject files].anyObject;

    UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:_movieViewController];
    navCon.modalPresentationStyle = UIModalPresentationFullScreen;
    [self.window.rootViewController presentViewController:navCon animated:YES completion:nil];
}

- (void)openMovieFromURL:(NSURL *)url
{
    if (!_movieViewController)
        _movieViewController = [[VLCMovieViewController alloc] initWithNibName:nil bundle:nil];

    _movieViewController.url = url;

    UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:_movieViewController];
    navCon.modalPresentationStyle = UIModalPresentationFullScreen;
    [self.window.rootViewController presentViewController:navCon animated:YES completion:nil];
}

Felix Paul Kühne's avatar
Felix Paul Kühne committed
324
@end