Skip to content

Run Google Play on an emulator and pretend to be any device

August 8, 2012

deejoy

Since the beginning of time man has sought to virtualize the human experience. We go to sleep and have life-like experiences in our dreams, we connect to internet sites like Chatroulette to virtually meet strangers (and inadvertently catch a glimpse of some old man balls from time to time), 1995 brought us the classic Denzel Washington/Russell Crowe sci-fi action thriller Virtuosity, and nerds gather in herds online to play StarCraft (myself included) and become virtual intergalactic heroes. The journey to virtualize reality has been a long time coming. The next logical step… to run Google Play on a virtual mobile device? “Of course!” said no one.

Alas, our journey continues. Our odyssey starts with the awesome blog post “Installing Google Play on Android Emulator.” The author, Piotr Buda, was able to successfully install the Google Play application on an emulator. However, you’ll notice that in the comments and subsequent blog post he (and his readers) were unable to download and install applications: the effects of the dastardly Error 491. Additionally, the applications they were able to view were severely limited. After reading both posts, the Apkudo team attempted to take it a step further and a) get downloads working and b) be able to browse and download any app.

Installing Google Play on an Android emulator requires three separate APKs: GoogleLoginService.apk, GoogleServicesFramework.apk, and Phonesky.apk (older versions will be named ‘Vending.apk’.) All three are located in the /system/app/ folder on your device. You can issue an adb pull command to pull each one off of your device (you generally don’t need root to pull). We pulled ours off of a Samsung Galaxy S III (the version of the store that we pulled was 3.5.16)

Next we just push the three APKs to install on the emulator (we made a simple modification to the shell script from the original blog post):

#!/bin/sh
echo "remounting..."
adb remount
echo "pushing login apk..."
adb push GoogleLoginService.apk /system/app/.
echo "pushing framework apk..."
adb push GoogleServicesFramework.apk /system/app/.
echo "pushing vending apk..."
adb push Phonesky.apk /system/app/.
echo "done"

Once the three APKs are installed, it is trivial to get the market executing. You’ll need to enter your account information when prompted and accept the market update if required (the update will generally not be successful, but it doesn’t seem to matter). You should now be able to browse and search the Play Store. Except, of course, you’ll usually hit an Error 491 when you try to download!

Solving Error 491

If you have created your AVD for ICS or earlier you will undoubtedly encounter Error 491 when attempting to download an application. The reason is that a shared object file, libdrmframework_jni.so is missing from the /system/lib/ folder. You may also find that the DrmProvider.odex and DrmProvider.apk files are missing from the /system/app/ folder. It seems that standard Android AVD images do not include these files. In order to circumvent this, you can build the Android platform from source (see http://source.android.com/source/initializing.html); your AVDs should now include the relevant DRM files. (Note: pulling the .so off of your device and pushing them to the emulator will generally not work.) You can also, of course, just create an AVD for 4.1 Jelly Bean: AVDs that target 4.1 appear to include those missing files and should be able to download applications easily.

Google Play on an emulator.

Move along, not too many apps to see here!

Downloading Solitaire. Side note: I’m pretty good at Solitaire.

Circumventing Google Play Filters

As you browse the Play Store you’ll notice a startling lack of available applications. The Google Play Store filters the apps that you can view based on a handful of factors relating to hardware, software, and carrier. You can find most filters listed here: http://developer.android.com/guide/google/play/filters.html

Depending on which features you give your AVD, you will see a variety of available apps. However, you’ll still be unable to view a great deal of what the store has to offer simply because your AVD lacks a great many features. Therefore, we’ll need to get our hands dirty with the innards of the Google Play code (this could probably be accomplished in a few other ways, but this was the most practical.)

The basic idea is to capture and mock all of the device identifying information and metadata that Play compiles before it is sent off on the wire. You’ll first need to unzip each APK: unzip {apk} -d {out_dir}. Then, remove the META-INF folder within each (we’ll re-sign each APK later.) Use baksmali on the classes.dex of both Phonesky.apk and GoogleServicesFramework.apk. Now you’ll have access to the smali code for each APK.

Inside the  decompiled GoogleServicesFramework you’ll find a file entitled /com/google/android/gsf/checkin/CheckinRequestBuilder.smali. Poke around a bit, and you’ll notice that it contains a host of device identifying information, all of which we must intercept and mock. Inside the decompiled Phonesky you’ll find two files entitled /com/google/android/finsky/utils/DeviceConfigurationHelper.smali and /com/google/android/finsky/utils/VendingUtils.smali respectively. Again, each file contains device identifying information that Google Play will eventually serialize, send off into the cloud, and use to filter the apps that you can view on the store.

So now that we know what data is being sent, how do we intercept it and mock it?  First, you’re going to need data to mock. This is relativley simple, as you can pull most of that information from a real phone using some combination of adb shell getprop, adb shell pm, and adb shell dumpsys. On the other hand, you can build a simple application that pulls all of this data and dumps it out in a neat little file. The next step is to build a framework for mocking data. I built a java class composed entirely of static methods (it is very easy to hand insert into smali code (with some register finagling)) that I compiled and then decompiled back into smali. Inside each of the decompiled Google APKs, make the appropriate directories for your classes package, and copy over the smali file. You should now be able to call any of your static methods from Google code.

Now its a matter of using grep to find the right method calls in the files mentioned above. For each method found, comment it out, and insert your own, mocked method call.  For example, in DeviceConfigurationHelper.smaliI’ve replaced the call

invoke-virtual {v4}, Landroid/content/pm/PackageManager;->getSystemAvailableFeatures()[Landroid/content/pm/FeatureInfo;

with a call to my own getSystemAvailableFeatures() method. Finally, you’ll need to use smali to re-compile all of the code back into a classes.dex file (replace the old ones in Phonesky and GoogleServicesFramework respectively), re-zip into each into an apk (including GoogleLoginService), and re-sign each using jarsigner. Push them onto the emulator as always and you should be good to go.

Play thinks we’re a Galaxy Nexus!

Downloading Angry Birds Space.

Playing our downloaded app on the emulator!

For now, you can only download and install free apps. As you might imagine, getting paid apps on an emulator is a bit trickier. We’ll save that for a later post.

Happy hacking,

-Daniel Joyce, Software Engineer

You may wish to reference the following:
Smali and Baksmali
Android Api
Google Play Filters

31 Comments

Post a comment
  1. August 9, 2012

    I’ve yet to try this, but if it worked for you, then awesome :D That 491 was nasty and I’m glad you came to a way to fix it. Well done.

    • Zsolt Farkas #
      November 17, 2012

      Thanks to Daniel and Piotr – I confirm that the steps of both guides have finally led me to successfully operate my emulator with Google Play Services. Error 491 could be eliminated by simply using API16 (gapps-gb-20110828-signed.zip from http://wiki.cyanogenmod.org/wiki/Latest_Version/Google_Apps).

  2. August 9, 2012

    I encountered a small typo that got me confused for a little:
    > Installing Google Play on an Android emulator requires three separate APKs: GoogleLoginService.apk, GoogleFrameworkServices.apk

    The last one should should have been GoogleServicesFramework.apk

  3. August 9, 2012

    Ah, thanks @AlexKBravo – typo fixed! Let us know how the process worked for you.

  4. Pj #
    August 14, 2012

    I’m not able to push apks to system/apk/.
    I tried everything to remount partition in rw mode but still its giving error “failed to copy:no space left” though there is enough space. plz help

    • deejoy #
      August 14, 2012

      Hey Pj. You need to run your emulator with the --partition-size flag. Set it to something like 512. Hopefully that solves your problem.

      • Pj #
        August 15, 2012

        Hey deejoy!
        thanks man! that worked. How Intelligently you guessed it ;)

  5. Chuck #
    August 29, 2012

    I keep getting “No space left on device” errors when I try to push those files. Any idea why?

    • deejoy #
      August 29, 2012

      Hello Chuck. Another poster, PJ, had a similar question. Run your emulator with the –partition-size flag and give it a value like 256 or 512. This should give you enough room to push those three APK’s onto the emulator.

      • Chuck #
        August 29, 2012

        Thanks! That allowed me to push the files. I’ll see if I can get the rest to work.

  6. Ramesh #
    September 7, 2012

    I tried this with Jelly Bean (4.1) Emulator. Everything worked fine and Play Store was installed on the Emulator jelly bean Emulator itself. But when I start the Play Store it starts to load & then quits. I used logcat to monitor and found the following exception thrown :

    09-07 17:31:32.023: D/dalvikvm(656): GC_EXPLICIT freed 49K, 6% free 8708K/9223K, paused 30ms+12ms, total 148ms
    09-07 17:31:32.033: E/StrictMode(656): class com.android.vending.AssetBrowserActivity; instances=3; limit=1
    09-07 17:31:32.033: E/StrictMode(656): android.os.StrictMode$InstanceCountViolation: class com.android.vending.AssetBrowserActivity; instances=3; limit=1
    09-07 17:31:32.033: E/StrictMode(656): at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
    09-07 17:31:32.113: I/Choreographer(656): Skipped 97 frames! The application may be doing too much work on its main thread.

    Could you please help me ??.

  7. Ramesh #
    September 7, 2012

    I have done some more debuggung and found the following on the LogCat. It would be a great help if you can help me out here.

    09-07 17:40:30.233: I/Choreographer(390): Skipped 33 frames! The application may be doing too much work on its main thread.
    09-07 17:40:30.333: I/Choreographer(656): Skipped 243 frames! The application may be doing too much work on its main thread.
    09-07 17:40:30.904: I/ActivityManager(147): Displayed com.android.vending/.AssetBrowserActivity: +2s400ms
    09-07 17:40:31.263: I/Choreographer(656): Skipped 94 frames! The application may be doing too much work on its main thread.
    09-07 17:40:31.763: I/Choreographer(656): Skipped 127 frames! The application may be doing too much work on its main thread.
    09-07 17:40:31.824: D/dalvikvm(656): WAIT_FOR_CONCURRENT_GC blocked 0ms
    09-07 17:40:31.934: D/dalvikvm(656): GC_EXPLICIT freed 151K, 6% free 8713K/9223K, paused 12ms+10ms, total 106ms
    09-07 17:40:31.944: E/StrictMode(656): class com.android.vending.AssetBrowserActivity; instances=3; limit=1
    09-07 17:40:31.944: E/StrictMode(656): android.os.StrictMode$InstanceCountViolation: class com.android.vending.AssetBrowserActivity; instances=3; limit=1
    09-07 17:40:31.944: E/StrictMode(656): at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
    09-07 17:40:59.114: E/ThrottleService(147): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)

    • deejoy #
      September 7, 2012

      Hey Ramesh,
      This is an error I would occasionally come across while working with the emulator. The offending error is:

      E/StrictMode(656): android.os.StrictMode$InstanceCountViolation: class com.android.vending.AssetBrowserActivity; instances=3; limit=1

      I can’t recall how to reproduce this error, but the easiest solution is to create a new AVD and scrap the one you are currently working with. You may also try to force quit and reset the cache of the currently running google play APK. Hope that helps.

      Edit: I haven’t tried this because I can’t reproduce your error right now, but you could also try adb shell ps and then kill all running vending processes.

      • Ramesh #
        September 7, 2012

        Hi deejoy,

        I fixed issue. I’m just mentioning it here just in case anyone else encounters the same issue.
        This issue came when I tried to install play store on my JB emulator first by pulling the above 03 apk’s from my nexus device running JellyBean.
        Then again (remembering that in this post it was pulled from an s3) I pulled the same 03 apk’s from my s3 running android 4.0.4 and this issue disappeared completely. I didn’t have to create a new emulator or anything. I just removed the previous 03 apk files from tnexus device running JellyBean from my JellyBean emulator & replaced them with the one’s from the s3 phone running ics.
        I can’t exactly explain why this would work. But it would be great if someone can so we know what exactly goes on here :). Cheers :). Thank you very mush for this blog post btw. I’m an official follower of your blog right now :)

  8. iA #
    September 14, 2012

    Have you tried installing the latest Chrome for Android on Android Emulator? After getting Play installed on Android Emulator 4.1. (http://papl.co/files/yotatech/Screen Shot 2012-09-14 at 4.53.49 PM.png screen shot of my emulator specs).

    Info about the Chrome Browser for Android from the Play site (https://play.google.com/store/apps/details?id=com.android.chrome&hl=en):
    CURRENT VERSION:
    18.0.1025308
    REQUIRES ANDROID:
    4.0 and up

    I had to do a search for Chrome. Once found, it said incompatible with my device and had no button to download. Is there anyway to get the latest Chrome running on emulator?

    • iA #
      September 14, 2012

      Sorry, hers’s that link again URL encoded so that it actually works : http://papl.co/files/yotatech/Screen%20Shot%202012-09-14%20at%204.53.49%20PM.png

      • deejoy #
        October 12, 2012

        Hey IA, sorry for the late reply. I’ve been incredibly busy. In any case, I did manage to get the latest chrome downloaded and installed on my emulator. However, when I run Chrome on the emulator I’m met with the following error: [ERROR:context_group.cc(83)] ContextGroup::Initialize failed because too few vertex attributes supported.

        So, what does that mean? Long story short, my emulator (even with OpenGL acceleration) does not support the required number of vertex attributes to run Chrome. You can take a look at Chrome’s source code here: code.google.com/p/chromium/source/browse/ Somewhere in context_group.cc (not necessarily line 83) you’ll see an explicit check for the number of available vertex attributes and the offending error message. As far as I know, theres not much you can do (if anything) to get past this error.

      • iA #
        October 12, 2012

        deejoy, thanks for your response, I posted it here at StackOverflow as well: http://stackoverflow.com/questions/12442667/how-to-run-the-new-chrome-for-android-4-on-android-emulator

      • deejoy #
        October 13, 2012

        Hey IA, hopefully that was of some use to you. Again, I’d like to apologize for that late response and I do hope you can find a work around or fix. Good luck.

      • January 20, 2013

        How did you get Chrome to install? Please share.

  9. Mpfan #
    October 19, 2012

    Hi there Deejoy
    Thank you for your awesome work.
    Can you please make a youtube or something else how to video?
    I’m just starting to run de emulator and i would love to try the regular apps.

    thnx

  10. Singh #
    October 30, 2012

    Hi,
    I am trying to follow the instructions and currently am stuck at the smali part of it all. Could you help me out? (or simply upload your version on the apk files for ics or jelly bean).

    Thanks

    • deejoy #
      December 20, 2012

      Hey Singh, unfortunately I can’t post my APK as it most likely violates some Google TOS (or some other legal jargon.) In any case, you’re going to need to have some working knowledge of APK structure: http://en.wikipedia.org/wiki/APK_(file_format), smali structure: http://code.google.com/p/smali/w/list, and java in general. More specifically, understand how smali registers work and how to set up method calls. Hand editing smali code is mostly an exercise in trial-and-error and liberal use of log statements. Good luck!

  11. netlon #
    November 11, 2012

    Regarding the 491 error, what’s probably happening is some DRM jar is missing – /etc/permissions/ would be the place to look. I say skip all that, just take out the check in the DownloadProvider and have checkCanHandleDownload return before it checks if it’s a DRM file. You have to compile AOSP, but, eh, that’s a good thing ;)

  12. December 8, 2012

    I delight in, result in I found just what I used to be looking for.
    You’ve ended my 4 day long hunt! God Bless you man. Have a nice day. Bye

  13. Hrishikesh #
    December 12, 2012

    When I reboot the emulator, google play disappears. Any ideas?

    • deejoy #
      December 20, 2012

      You’ll need to turn on emulator snapshots.

  14. December 20, 2012

    ok im actually a beginner at this and i basically dont understand this so i wanted to ask if there was some kind of video or something like that to help me

  15. January 20, 2013

    I managed to install Google Play using this method, but when I restart the emulator everything is gone and I have to install again. Anyone else have this problem?

  16. July 22, 2013

    If you are going for most excellent contents like me, simply pay a visit this site everyday for the
    reason that it presents quality contents, thanks

Trackbacks & Pingbacks

  1. Revue de l’actu Android pro du 19 août 2012 | Paris Android User Group

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 1,007 other followers

%d bloggers like this: