Upload Your Photos, Download Your Albums

Thursday, June 18, 2009 at 9:46 AM



In December, the Picasa Web Albums Uploader added support for downloading a photo album to your Mac. We've recently updated the Uploader to include the ability to download all photos from all albums in your account. To start the download, sign in to your account with the Picasa Web Albums Uploader application and select the Existing Album tab. Holding down the Mac's Option key will change the title of the Download Album button to Download All. Then one click will bring all of your albums home.

This update also improves reliability of the uploader's iPhoto export plug-in. The uploader typically keeps itself up-to-date, but you can also get the latest version, 1.3.1, from the download page. Please let us know how it works for you in the Mac Uploader area of the Picasa Help forum.

Introducing Google Quick Search Box

Tuesday, June 09, 2009 at 1:55 PM

When most people think of Google, search comes to mind – and rightly so! Hundreds of millions of people have come to know and love Google.com as their starting point for searching the Internet. About 2 years ago, we introduced Google Desktop to extend Google search capabilities to your Mac and, earlier this year, we launched a developer preview of the next evolution of search outside the browser. Today, we're officially releasing this technology to all users as the Google Quick Search Box (or QSB for short).


With Google Quick Search Box you can search for information from just about anywhere. As you type, suggestions will appear that match your query, ranging from applications and local files on your computer, to web search and navigational suggestions, to items from your browser history and contacts - and the types of results you can get will only grow over time! Check out the screenshot below for an example of the types of blended results you might see.


Once you've found the result you want, we wanted you to be able to DO something with it. To find out what you can do, select a result and press the tab key or the right arrow on the keyboard. Some examples of actions include instant messaging friends, playing a song, or emailing a URL. Just like the data you can search over, the list of actions you can perform will grow over time!

The quickest way to launch the Google Quick Search Box is by pushing Control + spacebar at the same time (Google Desktop devotees will still be able to press Command twice to summon the box). If you prefer another keyboard shortcut to summon the Google QSB, you can change it in the Preferences panel.

As you use the Google Quick Search Box more, it will learn which results you are likely to want. The goal here is that we get you to what you're looking for as quickly as possible. In the above example, if you chose Google Calendar, the next time you search for "cal", Google QSB will reorder the results so that you don't have to arrow down to your desired choice. Instead, you can just type "cal" and press enter.

Last, but definitely not least, the Google Quick Search Box is extensible. This means that anyone can create a plug-in that enables the QSB to search over additional data or perform more actions on results. As an example, we really enjoy the Twitter plug-in . After enabling that bad boy, we can send tweets right from the QSB and then do a Google search right after!

The Google QSB has allowed us to do our daily tasks faster. If you want to give it a try to see it speed up your day, visit www.google.com/quicksearchbox/.

If you're a Google Desktop user and you want to gain this functionality, you can learn more about Google QSB and see how to upgrade in this help center article.

And please, let us know what you think!

Posted by Ryan Tabone and Karen Grünberg, Product Managers

Mac OS X Spelunking in PowerPC and x86 Assembly, part 2

Thursday, June 04, 2009 at 11:53 AM



(Note: this is another of our occasional extra-geeky technical posts. If this isn't your thing, don't worry; our usual non-technical stuff will be back soon.)

Welcome back. In our last post we went through a simple function that made calls to other functions, and touched on stack frames and parameter passing. This time let's talk about a different function. We'll focus less on the things we've seen, and more on some more advanced actions that this function does.

UpdateDockTitle

PowerPC

<+0>: mflr    r0               // save linkage
<+4>: stmw r28,-16(r1) // stash r28, r29, r30, r31
<+8>: mr r30,r3 // save r3 (WindowData)
<+12>: bcl- 20,4*cr7+so,0x928d2bd4 <+16>
<+16>: mflr r31 // get ip in r31

Whoa... what?

Short story: <+12> is an unconditional branch-and-link.

Long story: On the PowerPC, instructions like bge, etc. are just aliases to a more primitive branch instruction, bc (branch conditional). In this case, the first parameter is 20 (0b10100), which indicates “branch always”. Since it's always going to branch, the second parameter doesn't matter, so it was set to all 1 bits (which translates to 4*cr7+so).

Why do this? Because we're going to need to access some PC-relative data, and the PowerPC chip has no PC-relative addressing mode. And the register move instructions can't access the PC register. Therefore we cheat in a way by taking an unconditional jump to the next address. Since it's a branch and link, the link register is filled with the next address (in this case, that equals the address just jumped to) which can be moved to a normal register.

Why branch-conditional with a condition “branch always”? The b opcode only provides absolute addressing. Only bc has relative addressing.

<+20>: stw     r0,8(r1)
<+24>: stwu r1,-80(r1) // make stack frame
<+28>: addis r28,r31,3533
<+32>: bl 0x928d2c50 <_Z15GetTitleForDockP10WindowData>
<+36>: lbz r0,-3364(r28) // haul initialization boolean into r0

This is where intuition comes in. We're hauling in some random byte from a PC-relative address. (lbz is load byte and zero, which loads one byte from memory and clears the high bits.) What's byte sized? A Boolean (the Carbon type; GCC makes C++ bools 4 bytes). Why a Boolean? Probably a flag. And with the value of the byte gating the call to RegisterAsDockClientPriv, it's a safe bet that it's an initialization flag.

<+40>: mr      r29,r3         // stash new title into r29
<+44>: cmpwi cr7,r0,0 // was initialized?
<+48>: bne- cr7,0x928d2c04 <+64> // if so, skip
<+52>: bl 0x9287f864 <_Z24RegisterAsDockClientPrivv> // else initialize
<+56>: li r0,1 // and set flag
<+60>: stb r0,-3364(r28) // as being intialized
<+64>: mr r3,r30
<+68>: mr r4,r29
<+72>: bl 0x928d2c68 <SyncPlatformWindowTitle> // call with (WindowData, new title)
<+76>: lwz r0,344(r30) // pull (WindowData + 344)
<+80>: andis. r2,r0,64 // and pull a flag bit out of it (minimized?)

More intuition here. r30 contains a pointer to the WindowData class instance, and we're accessing some word 344 bytes in. We don't care about the destination register (we don't touch r2 again this function) but don't miss the name of the opcode: “andis.” Remember that the period means to update cr0.

Once again, this is obviously a flag (bit-sized this time). But what does it mean? Context tells us that we only call CoreDockSetItemTitle when it's set. Thus, it's a safe guess that this is the is-minimized flag.

<+84>: beq-    0x928d2c38 <+116> // if not minimized, skip this step
<+88>: addi r1,r1,80
<+92>: lwz r3,196(r30) // load WID

How do I know that WindowData+196 is the CoreGraphics WID (CGWindowID; see CGWindow.h)? I used Quartz Debug to look at the window list for a sample app. The app only had one window, and the listed WID matched.

<+96>: mr      r4,r29 // load new title
<+100>: lwz r0,8(r1)
<+104>: lmw r28,-16(r1) // tear down stack frame
<+108>: mtlr r0
<+112>: b 0x92b58ce4 <dyld_stub_CoreDockSetItemTitle>

Note that we're tearing down the stack frame twice. In this case we're tail calling CoreDockSetItemTitle so that it's as if our caller called them directly. This is equivalent to the code return CoreDockSetItemTitle(wid, newTitle). Note from the setup of r3 and r4 that we can deduce the parameter types. Can we figure out the return type, though? Not really. The calling code ignores it, so we can ignore it too.

<+116>: addi    r1,r1,80
<+120>: li r3,0
<+124>: lwz r0,8(r1)
<+128>: lmw r28,-16(r1)
<+132>: mtlr r0
<+136>: blr

x86

<+0>: push   %ebp                   // make stack frame
<+1>: mov %esp,%ebp
<+3>: sub $0x28,%esp
<+6>: mov %ebx,-0xc(%ebp) // save %ebx
<+9>: call 0x92e4bbe4 <+14>
<+14>: pop %ebx // IP > %ebx

We're doing the same trick here to get the PC into a register and I'm a bit stumped as to why. From what I know, the x86 has PC-relative addressing, and surely there's got to be a better way to get the PC into a normal register. Right?

<+15>: mov    %esi,-0x8(%ebp)      // save %esi
<+18>: mov 0x8(%ebp),%esi // WindowData > %esi
<+21>: mov %edi,-0x4(%ebp) // save %edi

This almost looks like it was compiled by a different compiler. In the previous function, edi and esi are pushed, and then the stack pointer dropped. Here, we create the stack space and then move the contents of three registers (edi, esi, and ebx). I suspect that things change once we also have to save ebx, though I don't know why.

<+24>: mov    %esi,%eax            // %esi (WindowData) > %eax
<+26>: call 0x92e4bc40 <_Z15GetTitleForDockP10WindowData>

Whoa. If we're calling a function we need to set the parameter via stack-relative addressing off esp. What's going on here?

The point of an ABI is that it's a documented way for functions to call each other. But if a function, say GetTitleForDock(WindowData*), is a short one that's not public and is only used under controlled circumstances, why worry about setting up the stack? In this particular case, GetTitleForDock happens to be a nine-instruction routine. Not worth the hassle of a stack frame, so it's reasonable to pass in the one parameter in eax.

<+31>: cmpb   $0x0,0xd51a36c(%ebx) // test initialization boolean
<+38>: mov %eax,%edi // window title > %edi
<+40>: jne 0x92e4bc0c <+54> // if initialized, skip
<+42>: call 0x92df9fe0 <_Z24RegisterAsDockClientPrivv> // else initialize
<+47>: movb $0x1,0xd51a36c(%ebx) // and set flag as being initialized
<+54>: mov %edi,0x4(%esp) // new title (param 2)
<+58>: mov %esi,(%esp) // WindowData (param 1)
<+61>: call 0x92e4bc52 <SyncPlatformWindowTitle>
<+66>: xor %eax,%eax // clear %eax (noErr?)
<+68>: testb $0x2,0x159(%esi) // test flag (WindowData + 0x159) (minimized?)
<+75>: je 0x92e4bc35 <+95> // if not minimized, skip this step
<+77>: mov %edi,0x4(%esp) // new title (param 2)
<+81>: mov 0xc4(%esi),%eax // (WindowData + 0xC4) WID
<+87>: mov %eax,(%esp) // (param 1)
<+90>: call 0xa0a52ad1 <dyld_stub_CoreDockSetItemTitle>
<+95>: mov -0xc(%ebp),%ebx
<+98>: mov -0x8(%ebp),%esi
<+101>: mov -0x4(%ebp),%edi
<+104>: leave
<+105>: ret

Conclusion

Poking around in assembly isn't usually something you do every day. But whether you need it for debugging your own code or exploring someone else's, it's a skill that is definitely worth learning. PowerPC and x86 processors might have had a bit of a different history, but the code that's generated for either is certainly not as intractable as some suggest.

Where to go from here? Look around some more. Use otool -tV to dump binaries and see what they do. Use nm to see which symbols are exported from frameworks and watch how they work.

Go exploring, and have fun.

(Thanks to my editor, Scott Knaster, and to David Shayer, whose introductory session on PowerPC assembly at the legendary MacHack conference started me on this path.)

Google Chrome, Sandboxing, and Mac OS X

Tuesday, June 02, 2009 at 10:28 AM

Interested in news about Google Chrome for Mac OS X? Google Chrome for the Mac is coming along fine, and for the technically inclined, Jeremy Moskovich of the Google Chrome team has written a blog post explaining how the developers implemented sandboxing, an important Google Chrome feature. To find out more, please check out Jeremy's post.

Mac OS X Spelunking in PowerPC and x86 Assembly, part 1

Tuesday, May 26, 2009 at 4:11 PM

(Note: this is one of our occasional extra-geeky technical posts. If this isn't your thing, don't worry; our usual non-technical stuff will be back soon.)

If you're a programmer, there are many reasons why you might want to go exploring the inner workings of Mac OS X. You might want to learn how how Apple achieves interesting effects. Or perhaps you're just curious about how things work. (We're all adults here, so I won't lecture you about the dangers of using private or undocumented interfaces in your apps.)

In any case, though, you need to know how to read assembly, either PowerPC (if you have an older Mac) or x86 (if you have anything recent). While there are good resources available to learn about reading PowerPC assembly for exploration, there are fewer about x86. Despite the present and future of the Mac being x86, it seems like people have lots of anxiety about having to work with it.

I think the problem is not a lack of documentation on x86 assembly, but a surfeit of it. Most of it is Windows- or DOS-centric, usually with syntax that doesn't apply (Intel syntax vs the AT&T syntax that GCC uses), and with the aim of teaching how to write it. But reading x86 assembly really isn't that hard. If all you want to do is learn how to read the code generated by GCC, it's probably just as easy as PowerPC.

The other day I was investigating how window minimization and window titles work. While exploring, I took notes of my discoveries. Let's touch on two functions, in both PowerPC and x86 flavors.

Before we begin, I'm going to assume that you're comfortable with assembly in general (though not necessarily with any particular one). If you have the latest developer tools, launch Shark (in /Developer/Applications/Performance Tools) and in the Help menu you can access various ISA references. In addition, Apple has ABI documentation for both the PowerPC and x86. I'm going to go over each function twice (once for PowerPC and once for x86); feel free to skim the PowerPC version if you're accustomed to it. And finally, this is only for the 32-bit version of each platform; things change even more with 64 bits.

SetWindowTitleWithCFString

The trail always begins with a public call that uses the SPI that you want to figure out. In this case, I chose SetWindowTitleWithCFString because it has to somehow set the title of a window even if it's minimized. I went with Carbon because sometimes the dynamic nature of Objective-C with Cocoa makes tracing code harder.

PowerPC

<+0>: mflr    r0          // save linkage
<+4>: stmw r30,-8(r1) // stash r30, r31
<+8>: mr r30,r4 // save r4 (new title)
<+12>: stw r0,8(r1) // make stack frame
<+16>: stwu r1,-80(r1) // make stack frame

This is the prologue of the function. The PowerPC doesn't have a dedicated stack pointer (convention is to use r1 for that), so the common way of implementing branches by pushing the PC onto the stack doesn't work. Instead, the PowerPC has a link register and a command bl to branch and put the old PC value into the link register. Thus, almost every function starts with mflr r0, to pull the old PC into a usable register. Then in <+4> we save off some registers that we're going to smash. Every function needs scratch registers to hold local variables, and usually the high-numbered registers are used. The stmw (store multiple words) instruction is useful for ditching many high registers on the stack. Then in <+12> we drop the old PC onto the stack and allocate 80 bytes on the stack.

A note on parameter passing. Integer-sized parameters (the only kind we'll be dealing with today) are passed into a function starting with r3 and going up through the registers. Return values are returned in r3. So we see that in <+8> we stick away the pointer to the new name in r30 (whose previous value was stored on the stack earlier).

<+20>: bl      0x92881384 <_Z13GetWindowDataP15OpaqueWindowPtr>
<+24>: li r0,-5600 // errInvalidWindowRef
<+28>: cmpwi cr7,r3,0 // if no window data, bail
<+32>: beq- cr7,0x928d2ae0 <+60>
<+36>: cmpwi cr7,r30,0 // if no string to set, bail
<+40>: li r0,-50 // paramErr
<+44>: beq- cr7,0x928d2ae0 <+60>
<+48>: mr r4,r30

This is where we must start making inferences as to what the code is doing. Fortunately, we have the symbols so it's not too hard. We see that we use the WindowRef as a parameter to a C++ function GetWindowData(OpaqueWindowPtr), as the WindowRef was passed in as r3 and r3 wasn't altered before the call. In addition, note that the function return value, being in r3, will overwrite the WindowRef value which wasn't saved in a high register. That's fine, as the WindowRef was just an index into a table and won't be needed further.

At this point we run some checks. We compare both r3 and r30 to zero, and if either are zero we jump to the end with r0 set to the appropriate error code. (The end of the function will move r0 into r3 for return.)

The PowerPC condition register has eight condition sets. Why are we using cr7 here? Probably because cr7 is volatile and we can get away with not saving/restoring it.

<+52>: bl      0x928d2af8 <_ZN10WindowData14SetTitleCommonEPK10__CFString>
<+56>: li r0,0 // return noErr
<+60>: addi r1,r1,80 // tear down stack frame and return
<+64>: mr r3,r0
<+68>: lwz r0,8(r1)
<+72>: lmw r30,-8(r1)
<+76>: mtlr r0
<+80>: blr

The rest is pretty simple. We call a member function WindowData::SetTitleCommon(CFString*), and then do common tear down. We restore the stack pointer, put the return value into r3, restore the registers, move the old PC back into the link register, and branch to the link register (blr), returning us to our caller.

x86

The PowerPC register file is really easy: r0, r1, r2 ... r31. x86 has fewer registers and they've historically had different roles (accumulator, base, source index, destination index, and so on). Seriously, forget about that. There are eight registers you care about. eax, ebx, ecx, edx, esi, and edi are all general-purpose registers. esp is the stack pointer. ebp is the frame pointer. That's it.

PowerPC assembly reads right-to-left (except for stores). x86 AT&T syntax in general reads left-to-right.

<+0>: push   %ebp             // make stack frame
<+1>: mov %esp,%ebp // make stack frame
<+3>: push %esi // stash %esi
<+4>: sub $0x14,%esp // make stack frame

x86 is stack-based. Parameters to a function are put at the top of the stack, and the rightmost parameters have the highest addresses. To execute the function, the call instruction was used. This instruction pushes the PC onto the stack, so even before we hit <+0> the parameters are four bytes above the stack pointer. In <+0> we save off the old stack frame value and in <+1> we establish our stack frame. At this point ebp is fixed for the entire function. In <+3> we save the old values of registers we're going to use, and in <+4> we allocate space on the stack.

This is a perfect example of an ideal stack frame. ebp is the frame pointer. It points (to the stack) at the old frame pointer. ebp+4 is the PC of the function that called us. ebp+8 is the first parameter passed in, ebp+12 is the second, etc. Immediately below ebp are the values saved from the registers, which will be restored before the return. And below that is a bunch of stack space used for either register spillage or calling subsequent functions. One interesting note is that rarely are parameters pushed onto the stack for a call. The stack pointer doesn't move once we make it past the prologue. We just set the memory right above esp (the stack pointer) and make the call.

<+7>: mov    0x8(%ebp),%eax   // get WindowRef in %eax
<+10>: mov 0xc(%ebp),%esi // get new title in %esi

The parameters are passed on the stack. Since fiddling in memory is slow, we pull the values into registers. It's actually pretty analogous to how things go in PowerPC. There, lower registers like r3 are reused for parameter passing so important values are kept in the high registers. On x86 the parameters go on the stack and values are kept in registers when possible. Why eax and esi? Why not?

<+13>: mov    %eax,(%esp)      // put WindowRef on the stack
<+16>: call 0x92dfb8f6 <_Z13GetWindowDataP15OpaqueWindowPtr>

With the PowerPC, you can tell how many parameters a function has by seeing how many registers starting with r3 are loaded. Here, we just look at the register indirect addressing with esp.

<+21>: mov    %eax,%edx        // stick WindowData into %edx
<+23>: mov $0xffffea20,%eax // errInvalidWindowRef
<+28>: test %edx,%edx // if no window data, bail
<+30>: je 0x92e4bb04 <+54>
<+32>: test %esi,%esi // if no string to set, bail
<+34>: mov $0xffce,%ax // paramErr
<+38>: je 0x92e4bb04 <+54>

Return values come back from functions in eax, but otherwise this is pretty much the same. The only thing of interest to note is the clever use of the peculiar register structure. In <+23> the constant 0xffffea20 is loaded into eax. But on <+34> the constant 0xffce is loaded in ax. But since ax is just an alias for the lower 16 bits of eax, the upper half of the word is left as 0xffff and we get the full constant 0xffffffce in eax. Why do this? Because loading a 32 bit constant takes 5 bytes while loading a 16 bit constant only takes 4.

<+40>: mov    %esi,0x4(%esp)   // load new title as param 2
<+44>: mov %edx,(%esp) // load WindowData as param 1
<+47>: call 0x92e4bb0c <_ZN10WindowData14SetTitleCommonEPK10__CFString>
<+52>: xor %eax,%eax // return noErr

Same stuff as before. The one note is the zeroing of eax with an xor. Just a fancy trick as the generated code is faster and smaller than the equivalent mov $0x0,%eax.

<+54>: add    $0x14,%esp       // tear down stack frame and return
<+57>: pop %esi
<+58>: leave
<+59>: ret
<+60>: nop
<+61>: nop

The mirror image of the stack frame creation.

That's one function down and one left to go. Next time, we'll take a look at a function that behaves a little differently than this one did.

Google Spreadsheets power gFlashPro Flashcards for iPhone

Saturday, May 23, 2009 at 3:28 PM

Guest post by Mike MacDonald, Founder and CTO, gWhiz LLC

gFlashPro, the first offering in the iPhone App Store from our company, gWhiz, is a popular mobile flashcards application used by students of all ages to study on the go. Google Spreadsheets provide a key element of the gFlashPro architecture.

To create a gFlashPro flashcard set, students or teachers open up a new Google Spreadsheet and put questions in the first column, and answers (including multiple choice) in the adjacent columns. Meta-data (set description, search tags, runtime options, and so on) isn't required, but can be entered into a separate worksheet as simple key-value pairs. Then, on the iPhone or iPod touch, from within gFlashPro, users are given a list of the available flashcard sets (i.e., spreadsheets) for easy download. Alternatively, they can select flashcard sets from our catalog: a searchable repository of thousands of shared flashcard sets covering virtually any subject.




Once selected, the card set (spreadsheet) is downloaded into gFlashPro and presented to the user for mobile study and quizzing.



A few reasons we chose to use Google Spreadsheets:

  • We didn't want to have to write our own server-side flashcard creation code. If we "rolled our own", it would have been code that we'd need to maintain going forward. Using Google Spreadsheets allowed us to leverage the strength of Google's development team, the many built-in functions (e.g., importing .xls), and in the future, Google Gadgets.
  • Google's server infrastructure reliability is far better than anything we could possibly afford.
  • User authentication is handled by Google. While this is not a huge problem, it's just one more thing that our small development team doesn't need to deal with.

And a few lessons learned:

  • There are document limits for each account. In our case, the number and storage of documents is distributed across many thousands of users. Having a shared document in your account doesn't count against that limit.
  • While the Objective-C libraries for connecting to Google Docs are incredibly powerful, they are also fairly heavyweight for content-heavy apps like ours. We found that flashcard sets with more than 300 rows would blow out memory on the iPhone because of the substantial number of objects being created for each spreadsheet cell. One alternative we're considering in another application is to write our own XML parser to exclusively process spreadsheet data coming from Google.

Any questions? Just email us at info@gwhizmobile.com.

Updated Gmail and Calendar for iPhone

Tuesday, April 07, 2009 at 10:56 AM

Today I'm happy to announce that we've updated Gmail and Calendar for the iPhone. We've completely re-architected the code so you get more consistent performance, refreshed the user interface so it's easier to perform batch actions, and most importantly, laid the foundation which will allow us to iterate quickly and provide you with performance improvements and new features in the future.



To find out more about how you can get all the Gmail goodies, like threaded conversations, search, starring and labels, all on your iPhone, head on over to the Google Mobile Blog. Or, if you're convinced and want to try it out now, go to gmail.com on your iPhone. Click the Calendar link at the top to access Google Calendar. Please note that only iPhone OS 2.2.1 or higher is supported. We're rolling out this release over the next few days, so if you don't see the updated user interface, check back soon.



Posted by Deng-Kai Chen, Google Mobile