1

According to Are there APIs for custom vibrations in iOS? (that would have been as of iOS 5 / 6), AudioServicesPlaySystemSoundWithVibration() is used internally for vibration on iOS.

However I have tried hooking into on iOS 7, using MobileSubstrate... AudioServicesPlaySystemSoundWithVibration <- Doesn't seem to ever be called AudioServicesPlaySystemSound <- Gets called when silence switch is toggled, but no other vibrations AudioServicesPlayAlertSound <– Doesn't seem to ever be called

So the question is, what function (presumably still in AudioToolkit.framework, but maybe not) is used internally for vibration as of iOS 7?

Community
  • 1
  • 1

1 Answers1

3

I recently looked at how SpringBoard plays it's vibrations when you toggle silent switch or connect to power source. It only uses AudioServicesPlaySystemSound with same argument (0x452 for charging, 0x453 for silent switch) regardles of silent switch. Only place where I've seen AudioServicesPlaySystemSoundWithVibration call is when bulletin is added.

That applies to iOS 5-7. Only difference is on iOS 5 bulletins use AudioServicesPlaySoundWithBehavior because AudioServicesPlaySystemSoundWithVibration is only available starting at iOS 6.

UPDATE

Preferences app uses AudioServicesPlaySystemSound with 0x547 or 0x546 as argument. The reason you can't see that with MobileSubstrate is because Preferences app loads AudioToolbox framework at runtime using dlopen and then obtains pointer to AudioServicesPlaySystemSound with dlsym. To hook the function in that case you need to wait until Preferences app obtained the pointer and only then hook it.

UPDATE 2

SpringBoard also uses CoreMedia.framework APIs to play vibrations. All arguments here are just a guess from looking at disassembly. I don't have much experience with C structure arguments and floating-point instructions.

  • FigVibratorPlayVibrationWithDictionary(CFDictionaryRef pattern, BOOL, float). Last two arguments are unknown to me - they are set as NO and 1.0f.
  • FigVibratorPlayVibration(float, CMTime, CMTime, CTime).

Functions above are most likely to be used by iOS but there are some other functions worth hooking:

  • FigVibratorStartOneShot(float, CMTime)
  • FigVibratorStartRepeating. First argument is probably a float but don't know for others - it's some number of CMTime arguments.
creker
  • 9,400
  • 1
  • 30
  • 47
  • Right. But then there's all these other vibrations in iOS like when you toggle vibration within settings, get a notification, get a call, etc. and none of them use AudioServicesPlaySystemSound/AudioServicesPlaySystemSoundWithVibration. I had no idea about AudioServicesPlaySoundWithBehavior. Maybe that's what they use! Do you have the function definition/args for that? Also how did you find it? – tydbwjiiofj23iof2jiojf2ifj3i2 May 14 '14 at 13:51
  • AudioServicesPlaySoundWithBehavior is only for iOS5. It's missing since iOS6 - it's replaced by AudioServicesPlaySystemSoundWithVibration. I already told about notifications/bulletins - they use AudioServicesPlaySystemSoundWithVibration. At least, that's what I saw. – creker May 14 '14 at 14:10
  • I updated my answer with info about Preferences app. How I found all of that - disassembly. – creker May 14 '14 at 14:10
  • I am so incredibly impressed. This is exactly what I needed to know. I tried disassembling (I am new to the practice) Preferences yesterday, but was only able to see some ObjC message calls. Everything else was memory locations, and certainly no C function calls. – tydbwjiiofj23iof2jiojf2ifj3i2 May 14 '14 at 14:13
  • One last question I guess. Maybe you can answer it. If Preferences uses AudioServicesPlaySystemSound (but grabs it at runtime), I would go out on a limb and say that's how most other places in the OS use it as well, and why it wasn't getting called for me in any of those places because I was hooking it too early. I need to hook into *all* of it's calls though. Any idea what a good strategy for that would be? I guess I need to rehook the function everytime some part of the app dlopen/dlsym's it... – tydbwjiiofj23iof2jiojf2ifj3i2 May 14 '14 at 14:18
  • Yes, you could try to hook `dlsym` and rehook the function when it's loaded. You can even try to pass pointer to your own function when `dlsym` is called. That way you redirect calls without using MobileSubstrate. – creker May 14 '14 at 14:22
  • There is also another way of loading frameworks at runtime - `NSBundle`. Some iOS components use it. – creker May 14 '14 at 14:24
  • Good to know! However, internally wouldn't NSBundle still have to use dlopen? Maybe that's a silly question... – tydbwjiiofj23iof2jiojf2ifj3i2 May 14 '14 at 14:53
  • I tried hooking AudioServicesPlaySystemSound (as well as AudioServicesPlaySystemSoundWithVibration and AudioServicesPlayAlertSound for good measure) after the Preferences app is fully loaded, and still no calls to them are made when toggling vibrate in Preferences. Only when toggling with the physical switch. – tydbwjiiofj23iof2jiojf2ifj3i2 May 14 '14 at 17:10
  • The function is loaded on it's first call, not on app launch. There is a wrapper class inside preferences app that plays sounds. When you first call his methods it will `dlopen` the framework using `dispatch_once`. And on every call it will obtain function pointer with `dlsym`. `SoundPrefController -(void)playSound:(int)` - that's where it all happens. It called from here `SoundsPrefController -(void)setVibrate:(id) specifier:(id)` – creker May 14 '14 at 17:51
  • That's what I thought, so I tried hooking AudioServicesPlaySystemSound after making some vibrates in Preferences, then doing it some more, and still nothing. Furthermore, I tried hooking dlsym, which gets called a lot, but not once after opening Preferences or causing vibrates. dlopen also gets called a lot, but not after opening Preferences (there's only one logged call to dlopen of AudioToolbox and it's near respring of the device). – tydbwjiiofj23iof2jiojf2ifj3i2 May 14 '14 at 17:56
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/52699/discussion-between-creker-and-mathew-huusko-v) – creker May 14 '14 at 18:00
  • The last thing I'm yet to figure out is what an alarm/timer uses for vibration. AudioServicesPlaySystemSound/AudioServicesPlaySystemSoundWithVibration covers Contacts, Preferences, banner alerts, toggle side switch... but not alarms/timers... – tydbwjiiofj23iof2jiojf2ifj3i2 May 15 '14 at 01:27
  • So it looks like alarms are done with a SBUISound, which plays when the timer fires via "playInEvironments:completion:" However I'm not picking up any AudioServicesPlaySystemSound/AudioServicesPlaySystemSoundWithVibration calls for the vibration, even though the SBUISound vibrates via its "vibrationPattern" (NSDictionary). And even then, incoming call ringtones don't seem to use SBUISound, they use something else.. – tydbwjiiofj23iof2jiojf2ifj3i2 May 15 '14 at 03:24
  • Amazing. Them being in CoreMedia makes some sense given the context. Thanks! – tydbwjiiofj23iof2jiojf2ifj3i2 May 15 '14 at 13:09