Skip to content

Commit

Permalink
- properly handle background audio for ios 4.0
Browse files Browse the repository at this point in the history
- fixed double alert problem and added test case (iphone)
- show activity indicator when loading video (iphone)
  • Loading branch information
Jeff Haynie committed Jul 5, 2010
1 parent 214b331 commit aaf61c3
Show file tree
Hide file tree
Showing 34 changed files with 410 additions and 115 deletions.
21 changes: 21 additions & 0 deletions demos/KitchenSink/Resources/examples/alert.js
Expand Up @@ -90,3 +90,24 @@ button3.addEventListener('click', function()
win.add(button3);


//
// Double alert
//
var button4 = Titanium.UI.createButton({
title:'Double Alert',
height:40,
width:200,
top:160
});

button4.addEventListener('click', function()
{
// test firing 2 alerts in a row, should show the
// first and after you click OK, should then show the next
alert("You should see this first");
alert("Now you should see this one, assuming you dismissed the first alert");
});

win.add(button4);


6 changes: 3 additions & 3 deletions demos/KitchenSink/Resources/examples/camera_video.js
Expand Up @@ -50,7 +50,7 @@ cameraFlash.addEventListener('click',function()

var cameraType = Ti.UI.createButton({
color:'#fff',
title:"rear",
title:"front",
top:20,
right:20,
height:40,
Expand All @@ -71,12 +71,12 @@ for (var c=0;c<cameras.length;c++)
{
if (Ti.Media.camera == Ti.Media.CAMERA_FRONT)
{
cameraType.title = "rear";
cameraType.title = "front";
Ti.Media.switchCamera(Ti.Media.CAMERA_REAR);
}
else
{
cameraType.title = "front";
cameraType.title = "rear";
Ti.Media.switchCamera(Ti.Media.CAMERA_FRONT);
}
});
Expand Down
19 changes: 15 additions & 4 deletions demos/KitchenSink/Resources/examples/movie_remote.js
Expand Up @@ -16,14 +16,25 @@ if (parseFloat(Titanium.Platform.version) >= 3.2)
win.add(activeMovie);
}

var windowClosed = false;

activeMovie.addEventListener('complete',function()
{
Titanium.UI.createAlertDialog({title:'Movie', message:'Completed!'}).show();
if (!windowClosed)
{
Titanium.UI.createAlertDialog({title:'Movie', message:'Completed!'}).show();
}
win.close();
});

activeMovie.play();

win.addEventListener('close', function() {
activeMovie.stop();
});
win.addEventListener('close', function()
{
if (!windowClosed)
{
windowClosed = true;
alert("Window closed");
activeMovie.stop();
}
});
1 change: 1 addition & 0 deletions demos/KitchenSink/Resources/examples/movie_remote2.js
Expand Up @@ -20,5 +20,6 @@ activeMovie.play();


win.addEventListener('close', function() {
alert("Window closed");
activeMovie.stop();
});
1 change: 1 addition & 0 deletions demos/KitchenSink/Resources/examples/network.js
Expand Up @@ -28,3 +28,4 @@ Titanium.Network.addEventListener('change', function(e)
var networkTypeName = e.networkTypeName;
label2.text = 'Change fired net type:' + type + ' online:' + online + ' name:'+networkTypeName;
});

8 changes: 7 additions & 1 deletion demos/KitchenSink/Resources/examples/sound.js
Expand Up @@ -12,7 +12,13 @@ if (Titanium.Platform.name == 'iPhone OS')
{
data.push({title:'Record', hasChild:true, test:'../examples/sound_record.js'});
data.push({title:'Audio Session Mode', hasChild:true, test:'../examples/sound_session_mode.js'});


Ti.include("version.js");

if (isiOS4Plus())
{
data.push({title:'Background Audio', hasChild:true, test:'../examples/sound_bg.js'});
}
}

// create table view
Expand Down
32 changes: 32 additions & 0 deletions demos/KitchenSink/Resources/examples/sound_bg.js
@@ -0,0 +1,32 @@
var win = Ti.UI.currentWindow;


var button = Ti.UI.createButton({
title:"Start",
width:100,
height:40,
bottom:20
});

win.add(button);

var text = Ti.UI.createLabel({
text:"Click the button to start the audio and then exit the app.\n\nThe audio should continue playing and you can use the controls to control the media.",
width:"auto",
height:"auto",
top:10,
left:10,
right:10
});

win.add(text);

var sound = Titanium.Media.createSound({url:'../cricket.wav'});

button.addEventListener('click',function()
{
sound.audioSessionMode = Ti.Media.AUDIO_SESSION_MODE_PLAYBACK;
sound.looping = true;
sound.play();
});

10 changes: 9 additions & 1 deletion iphone/Classes/KrollContext.mm
Expand Up @@ -87,6 +87,7 @@ static TiValueRef MakeTimer(TiContextRef context, TiObjectRef jsFunction, TiValu
static double kjsNextTimer = 0;
[timerIDLock lock];
double timerID = ++kjsNextTimer;
[timerIDLock unlock];

KrollContext *ctx = GetKrollContext(context);
TiGlobalContextRef globalContext = TiContextGetGlobalContext(context);
Expand All @@ -100,7 +101,6 @@ static TiValueRef MakeTimer(TiContextRef context, TiObjectRef jsFunction, TiValu
[ctx registerTimer:timer timerId:timerID];
[timer start];
[timer release];
[timerIDLock unlock];
return TiValueMakeNumber(context, timerID);
}

Expand Down Expand Up @@ -637,6 +637,10 @@ -(void)main
queue_count = [queue count];
[lock unlock];

#if CONTEXT_DEBUG == 1
NSLog(@"CONTEXT<%@>: shutdown, queue_count = %d",self,queue_count);
#endif

// we're stopped, nothing in the queue, time to bail
if (queue_count==0)
{
Expand Down Expand Up @@ -748,6 +752,10 @@ -(void)main
NSLog(@"CONTEXT<%@>: woke up for new event (count=%d)",self,KrollContextCount);
#endif
}

#if CONTEXT_DEBUG == 1
NSLog(@"CONTEXT<%@>: is shutting down",self);
#endif

// call before we start the shutdown while context and timers are alive
if (delegate!=nil && [delegate respondsToSelector:@selector(willStopNewContext:)])
Expand Down
13 changes: 12 additions & 1 deletion iphone/Classes/TiApp.mm
Expand Up @@ -15,10 +15,12 @@
#import "TiDebugger.h"
#import "ImageLoader.h"
#import <QuartzCore/QuartzCore.h>
#import <AVFoundation/AVFoundation.h>

TiApp* sharedApp;

extern NSString * const TI_APPLICATION_DEPLOYTYPE;
extern void UIColorFlushCache();

#define SHUTDOWN_TIMEOUT_IN_SEC 10

Expand Down Expand Up @@ -254,6 +256,11 @@ - (void)boot

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];


#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
#endif
}

- (void)booted:(id)bridge
Expand Down Expand Up @@ -356,7 +363,7 @@ - (void)applicationWillTerminate:(UIApplication *)application

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
//FIXME: UIColorFlushCache();
[Webcolor flushCache];
[kjsBridge gc];
#ifdef USE_TI_UIWEBVIEW
[xhrBridge gc];
Expand Down Expand Up @@ -385,6 +392,10 @@ - (void)applicationDidBecomeActive:(UIApplication *)application
[[NSNotificationCenter defaultCenter] postNotificationName:kTiResumeNotification object:self];
}

-(void)applicationDidEnterBackground:(UIApplication *)application
{
}

-(void)applicationWillEnterForeground:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:kTiResumeNotification object:self];
Expand Down
2 changes: 1 addition & 1 deletion iphone/Classes/TiBase.h
Expand Up @@ -432,7 +432,7 @@ extern NSString * const kTiResumeNotification;
extern NSString * const kTiAnalyticsNotification;
extern NSString * const kTiRemoteDeviceUUIDNotification;
extern NSString * const kTiGestureShakeNotification;

extern NSString * const kTiRemoteControlNotification;

#ifndef __IPHONE_3_2
#define __IPHONE_3_2 30200
Expand Down
1 change: 1 addition & 0 deletions iphone/Classes/TiBase.m
Expand Up @@ -39,6 +39,7 @@ CGPoint midpointBetweenPoints(CGPoint a, CGPoint b)
NSString * const kTiAnalyticsNotification = @"TiAnalytics";
NSString * const kTiRemoteDeviceUUIDNotification = @"TiDeviceUUID";
NSString * const kTiGestureShakeNotification = @"TiGestureShake";
NSString * const kTiRemoteControlNotification = @"TiRemoteControl";



2 changes: 1 addition & 1 deletion iphone/Classes/TiColor.m
Expand Up @@ -18,7 +18,7 @@ +(id)colorNamed:(NSString *)name

if ([name caseInsensitiveCompare:@"default"] != NSOrderedSame)
{ //Default is allowed nil, while still counting as a color to stop inheritance.
translatedColor = UIColorWebColorNamed(name);
translatedColor = [Webcolor webColorNamed:name];
if(translatedColor == nil)
{
return nil;
Expand Down
1 change: 0 additions & 1 deletion iphone/Classes/TiMediaAudioPlayerProxy.h
Expand Up @@ -39,7 +39,6 @@
@property (nonatomic,readonly) NSNumber *STATE_STOPPED;
@property (nonatomic,readonly) NSNumber *STATE_PAUSED;


@end

#endif
66 changes: 65 additions & 1 deletion iphone/Classes/TiMediaSoundProxy.m
Expand Up @@ -8,6 +8,7 @@

#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVAudioPlayer.h>
#import <AVFoundation/AVAudioSession.h>

#import "TiMediaSoundProxy.h"
#import "TiUtils.h"
Expand Down Expand Up @@ -78,13 +79,20 @@ -(id)_initWithPageContext:(id<TiEvaluator>)context_ args:(NSArray*)args
}
volume = 1.0;
resumeTime = 0;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0

This comment has been minimized.

Copy link
@sptramer

sptramer Jul 5, 2010

Contributor

Using the __IPHONE_OS_VERSION_MAX_ALLOWED macro is not a good idea - it will cause crashes on 3.2 and earlier. Use +[TiUtils isiOS4OrGreater] instead, especially when calling methods which do not exist in earlier iOS versions.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(remoteControlEvent:) name:kTiRemoteControlNotification object:nil];
#endif
}
return self;
}

-(void)dealloc
{
[[TiMediaAudioSession sharedSession] stopAudioSession];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
[[NSNotificationCenter defaultCenter] removeObserver:self];
#endif
[super dealloc];
}

Expand Down Expand Up @@ -148,6 +156,7 @@ -(void)play:(id)args
// indicate we're going to start playing
[[TiMediaAudioSession sharedSession] playback:sessionMode];

paused = NO;
[[self player] play];
}

Expand All @@ -159,13 +168,15 @@ -(void)stop:(id)args
[player setCurrentTime:0];
}
resumeTime = 0;
paused = NO;
}

-(void)pause:(id)args
{
if (player!=nil)
{
[player pause];
paused = YES;
}
}

Expand All @@ -178,13 +189,15 @@ -(void)reset:(id)args
[player play];
}
resumeTime = 0;
paused = NO;
}

-(void)release:(id)args
{
if (player!=nil)
{
resumeTime = 0;
paused = NO;
[player stop];
RELEASE_TO_NIL(player);
}
Expand Down Expand Up @@ -319,7 +332,7 @@ -(void)setAudioSessionMode:(NSNumber*)mode
{
UInt32 newMode = [mode unsignedIntegerValue]; // Close as we can get to UInt32
if (newMode == kAudioSessionCategory_RecordAudio) {
NSLog(@"Invalid mode for audio player... setting to default.");
NSLog(@"[WARN] Invalid mode for audio player... setting to default.");
newMode = kAudioSessionCategory_SoloAmbientSound;
}
sessionMode = newMode;
Expand Down Expand Up @@ -367,6 +380,57 @@ - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)
}
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags
{
if (flags != AVAudioSessionInterruptionFlags_ShouldResume)
{
[self stop:nil];
}

if ([self _hasListeners:@"resume"])
{
NSDictionary *event = [NSDictionary dictionaryWithObjectsAndKeys:NUMBOOL(YES),@"interruption",nil];
[self fireEvent:@"resume" withObject:event];
}
}

- (void)remoteControlEvent:(NSNotification*)note
{
UIEvent *event = [[note userInfo]objectForKey:@"event"];
switch(event.subtype)
{
case UIEventSubtypeRemoteControlTogglePlayPause:
{
if (paused)
{
[self play:nil];
}
else
{
[self pause:nil];
}
break;
}
case UIEventSubtypeRemoteControlPause:
{
[self pause:nil];
break;
}
case UIEventSubtypeRemoteControlStop:
{
[self stop:nil];
break;
}
case UIEventSubtypeRemoteControlPlay:
{
[self play:nil];
break;
}
}
}
#endif

@end

Expand Down

0 comments on commit aaf61c3

Please sign in to comment.