Safely Installing Front Row on Lion 

FrontRow

I read at Macworld.com that Apple's Front Row has been removed from Mac OS X 10.7 Lion. They also include instructions on how to install Front Row on Lion, by copying off the binaries from a Snow Leopard installation, and then copying them into your /System folders on Lion.

I'm not a heavy user of Front Row so I am ambivalent about its removal. But the instructions on how to install Front Row really bother me. This is a really dangerous thing to do. The /System folder is reserved for Apple, and you could break your system badly by mucking with these directories. Don't do it.

So as an alternative, I will document how you can run Front Row on Lion without doing anything bad to your Lion system. The solution is to modify Front Row to be a self-contained, drag-and-droppable application (like any self-respecting Mac app should be) using the standard tricks of the trade for dynamic libraries that 3rd party Mac developers are required to use (who don't get to write to system folders).


Requirements and Caveats:

First, you need a copy of the original Front Row binaries from a Snow Leopard system.

  • /System/Library/CoreServices/Front Row.app
  • /System/Library/PrivateFrameworks/BackRow.framework
  • /System/Library/PrivateFrameworks/iPhotoAccess.framework
  • /System/Library/LaunchAgents/com.apple.RemoteUI.plist
  • /Applications/Front Row.app

This solution will require some command line tools which means you probably need to install Xcode (with the Unix support tools checked). 


You may notice that there are two "Front Row.app" applications listed. The one in the CoreServices folder is the one that contains all the real logic/code. All the instructions here are about the CoreServices application. The one in /Applications seems to be some kind of additional launcher which also contains a prettier icon. You don't actually need the one in Applications to use Front Row and  the solution presented here doesn't seem to work with that one. So be warned. 

Also, the RemoteUI.plist is not directly connected to this solution. I believe it is responsible for the daemon service that responds to the remote controls that used to ship with Macs. But I currently don't have a Lion system with those remotes to test.


Theory and Approach:

The Front Row.app in CoreServices is an application that dynamically links to the BackRow.framework and the iPhotoAccess.framework. On OS X, when you launch an application, it must find all the frameworks it depends on. To accomplish this, the application contains information about where to find the frameworks. This location information was recorded when the application was originally built and the location information itself was copied from inside the frameworks it was linked to at build time.

Both Backrow.framework and iPhotoAccess.framework say they are supposed to be installed to /System/Library/PrivateFrameworks. And the Front Row.app is instructed to look for those frameworks there. We can prove this by running the command line tool 'otool'.


Running on the Backrow.framework:

otool -L /System/Library/PrivateFrameworks/BackRow.framework/BackRow 

The tool will output a lot of stuff, but the first line under the architecture description shows where the framework is supposed to be installed:

/System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow (compatibility version 1.0.0, current version 1.0.0)


Repeat again for iPhotoAccess.framework:

otool -L /System/Library/PrivateFrameworks/iPhotoAccess.framework/iPhotoAccess 

/System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess (compatibility version 1.0.0, current version 1.0.0)


Finally, if we run otool on Front Row.app, we can see its list of dependencies. There are a lot, but the ones we care most about are BackRow and iPhotoAccess.

otool -L /System/Library/CoreServices/Front\ Row.app/Contents/MacOS/Front\ Row 

/System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess (compatibility version 1.0.0, current version 1.0.0)

/System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow (compatibility version 1.0.0, current version 1.0.0)


As a 3rd party Mac developer myself with a lot of experience with dynamic libraries due to being both a user and contributor of LGPL licensed software, we are not allowed to do what Apple has done and put frameworks in /System. In fact, we are discouraged from putting them anywhere except inside the .app bundle itself. This poses a technical problem since if the user can drag-and-drop their application anywhere, we don't know the absolute path to the frameworks inside the bundle ahead of time. 

To solve this problem, Apple has several magic 'anchors' that allow developers to specify relative paths. We are going to use the anchor: @executable_path. This basically uses the location of the application's underlying Unix executable as the root of the path.

By convention and Apple guidelines, frameworks go inside the .app bundle in Contents/Frameworks. So path for each framework should start with @executable_path/../Frameworks.

Thus our solution will be to modify Front Row.app so the frameworks are contained inside the .app bundle and everything is self-contained, thus avoiding the need to install anything to /System.

It is a little unusual to change the paths after the binary has already been built and shipped. But fortunately, Apple has a tool that lets us do just that. It is called install_name_tool.


Doing the work

Copy the Front Row.app from CoreServices and the Backrow.framework and iPhotoAccess.framework to a directory you have write access to (e.g. your home directory). We are going to modify these binaries. (Make sure you have a backup of these files if you don't want to lose the originals.)

Assuming all 3 items are in the same directory, using Terminal.app, cd into that directory and run the following commands.



1) Change the install locations of the frameworks

install_name_tool -id @executable_path/../Frameworks/BackRow.framework/Versions/A/iPhotoAccess BackRow.framework/Versions/A/BackRow

install_name_tool -id @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess iPhotoAccess.framework/Versions/A/iPhotoAccess


2) Embed the frameworks inside Front Row.app

mkdir -p Front\ Row.app/Contents/Frameworks
mv BackRow.framework Front\ Row.app/Contents/Frameworks
mv 
iPhotoAccess.framework Front\ Row.app/Contents/Frameworks


3) Change the locations that Front Row.app looks for the frameworks, i.e. instead of /System, look inside the bundle itself.

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/MacOS/Front\ Row

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/MacOS/Front\ Row


4) Annoyingly, we are not quite done. Inside the Front Row.app bundle in Contents/PlugIns, are additional PlugIns, each which also dynamically link two our two frameworks. 

DVD.frappliance/        Movies.frappliance/     Podcasts.frappliance/
FRSettings.frappliance/ Music.frappliance/      TV.frappliance/
FRSources.frappliance/  Photos.frappliance/

So we need to change the locations these PlugIns look in for the frameworks too.

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/DVD.frappliance/Contents/MacOS/DVD

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/DVD.frappliance/Contents/MacOS/DVD

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/FRSettings.frappliance/Contents/MacOS/FRSettings

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/FRSettings.frappliance/Contents/MacOS/FRSettings

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/FRSources.frappliance/Contents/MacOS/FRSources

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/FRSources.frappliance/Contents/MacOS/FRSources

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/Movies.frappliance/Contents/MacOS/Movies

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/Movies.frappliance/Contents/MacOS/Movies

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/Music.frappliance/Contents/MacOS/Music

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/Music.frappliance/Contents/MacOS/Music

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/Photos.frappliance/Contents/MacOS/Photos

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/Photos.frappliance/Contents/MacOS/Photos

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/Podcasts.frappliance/Contents/MacOS/Podcasts

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/Podcasts.frappliance/Contents/MacOS/Podcasts

install_name_tool -change /System/Library/PrivateFrameworks/BackRow.framework/Versions/A/BackRow @executable_path/../Frameworks/BackRow.framework/Versions/A/BackRow Front\ Row.app/Contents/PlugIns/TV.frappliance/Contents/MacOS/TV

install_name_tool -change /System/Library/PrivateFrameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess @executable_path/../Frameworks/iPhotoAccess.framework/Versions/A/iPhotoAccess Front\ Row.app/Contents/PlugIns/TV.frappliance/Contents/MacOS/TV


5) We're in the home stretch. You now have a drag-and-droppable application. You might want to copy your newly modified Front Row.app to your Lion system if you aren't already on Lion.

6) Because Apple digitally signs their applications, and because we modified their binaries, you will not be able to run the binary because the operating system is trying to protect you from malicious people altering binaries they don't own in bad ways trying to spread malware and viruses. You can't get Apple to resign your app, but you can resign the binary with your own certificate and tell the operating system you accept binaries signed with your certificate.

I'm not going to go over how to create a self-signed certificate to codesign your application. Apple and other places have that covered. Use Certificate Assistant in Keychain Access to do it. See Apple's documentation here:

http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html


Once you have your certificate, use the codesign tool to resign the app. Use the certificate name you specified when you created the certificate.

codesign -f -s "My Self Signed Certificate" "/path/to/Front Row.app"


Running Front Row

In Finder, double-click the app  (you may be asked if you want to accept your certificate...say yes) and immediately hit the Esc key. For some reason, this is how I must always launch Front Row, even with Apple's normal version on Snow Leopard. I think it was intended to only be launched from a remote control. 

But whatever the case, Front Row should now be running on your Lion system.


Loose Ends

There are two loose ends: the other Front Row.app binary and the com.apple.RemoteUI.plist file.

First, I don't know what to do with the Front Row.app binary or what it is really supposed to do. Things work without it, so I'm unmotivated to spend more time on it. (A Dtrace guru probably could you everything you wanted to know about this app.)

Second, I believe the com.apple.RemoteUI.plist is supposed to be the daemon for the remote control. I don't have a remote control to test with so I can't do much with this.

If you edit the com.apple.RemoteUI.plist file, you will see a hardcoded path to the FrontRow.app in CoreServices. If you want to try to get this working, I recommend you change this path to wherever you put your new modified Front Row.app.

Next, do not put the file in /System/Library/LaunchAgents. Either /Library/LaunchAgents or ~/Library/LaunchAgents is where this stuff goes.

I don't remember the proper way to put stuff in these folders. (launchctl?). So if you just copy in the file Launch Services may not immediately react to the new instructions. You might have to reboot your computer to force launchd to take notice.

If you get this stuff working, I would love to hear about it.


Conclusion

While more work than writing in your /System folders, this solution is much safer for the health of your computer. Be aware, this doesn't guarantee Front Row will work correctly, but at least you won't destroy vital operating system files in the process.

So that's my long spiel for an app I hardly use. If you feel generous, please consider a donation for my hard work :)




Copyright © PlayControl Software, LLC / Eric Wing