[Android] How to unlock and root your Pixel XL with Homebrew and the Android SDK

I was gifted a Pixel XL through Google’s very generous RMA program for Nexus 6P owners who were suffering from early shutdown issues. Praise be to Google.

Moving away from a phone that would randomly turn itself off was a breath of fresh air, but as with all of my newly acquired Android devices, unlocking the bootloader and gaining root access was a necessity.

Prerequisites:

My preferred method for installing packages in OSX is through Homebrew. Homebrew is a package manager that allows you to install tools from its public repository. All tools are installed in its own directory that are then symlinked to the /usr/local directory, which makes installing multiple versions of the same tool and switching between those versions extremely convenient.

If you prefer to install Android Studio or the Android SDK independently without Homebrew, you can download both from the link above, else this guide will continue with Homebrew.

Installing Homebrew

Per the install instructions, we will run the following:

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following new directories will be created:
/usr/local/Cellar
/usr/local/Homebrew
/usr/local/Frameworks
/usr/local/include
/usr/local/opt
/usr/local/sbin
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
==> Cleaning up /Library/Caches/Homebrew...
==> Migrating /Library/Caches/Homebrew to /Users/raph/Library/Caches/Homebrew...
==> Deleting /Library/Caches/Homebrew...
Already up-to-date.
==> Installation successful!

Installing the Android SDK

After the Homebrew installation, we will want to install the android-sdk. Most tools are located in the homebrew-core repository, but the android-sdk has recently moved to the homebrew-cask repository, so we will need to tap that cask.

$ brew tap caskroom/cask
==> Tapping caskroom/cask
Cloning into '/usr/local/Homebrew/Library/Taps/caskroom/homebrew-cask'...
remote: Counting objects: 3853, done.
remote: Compressing objects: 100% (3837/3837), done.
remote: Total 3853 (delta 30), reused 547 (delta 12), pack-reused 0
Receiving objects: 100% (3853/3853), 1.32 MiB | 4.79 MiB/s, done.
Resolving deltas: 100% (30/30), done.
Checking out files: 100% (3838/3838), done.
Tapped 0 formulae (3,862 files, 4.1MB)

Now that the cask is tapped, we will go ahead and pour ourselves a nice android-sdk flavored brew:

$ brew cask install android-sdk
==> Caveats
android-sdk requires Java 8. You can install it with
brew cask install caskroom/versions/java8
We will install android-sdk-tools, platform-tools, and build-tools for you.
You can control android sdk packages via the sdkmanager command.
You may want to add to your profile:
'export ANDROID_SDK_ROOT=/usr/local/share/android-sdk'
This operation may take up to 10 minutes depending on your internet connection.
Please, be patient.
==> Satisfying dependencies
==> Downloading https://dl.google.com/android/repository/sdk-tools-darwin-3859397.zip
######################################################################## 100.0%
==> Verifying checksum for Cask android-sdk
==> Installing Cask android-sdk

🍺 android-sdk was successfully installed!

Installing Java 8

The install notes for the android-sdk kindly reminds us that we will need Java 8 as well and provides us with the command to do so:

$ brew cask install caskroom/versions/java8
==> Tapping caskroom/versions
==> Caveats
This Cask makes minor modifications to the JRE to prevent issues with
packaged applications, as discussed here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=411361
If your Java application still asks for JRE installation, you might need
to reboot or logout/login.
Installing this Cask means you have AGREED to the Oracle Binary Code
License Agreement for Java SE at
https://www.oracle.com/technetwork/java/javase/terms/license/index.html
==> Satisfying dependencies
==> Downloading http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/jdk-8u144-macosx-x64.dmg
######################################################################## 100.0%
==> Verifying checksum for Cask java8
==> Installing Cask java8
==> installer: The upgrade was successful.
🍺 java8 was successfully installed!

Installing jEnv to manage Java environments

With Java 8 successfully installed, let’s take a quick pause to install jEnv which will let us easily switch between different Java versions.

$ brew install jenv
==> Downloading https://github.com/gcuisinier/jenv/archive/0.4.4.tar.gz
==> Downloading from https://codeload.github.com/gcuisinier/jenv/tar.gz/0.4.4
######################################################################## 100.0%
🍺 /usr/local/Cellar/jenv/0.4.4: 78 files, 66KB, built in 3 seconds

With jenv installed, we will want to add the following to ~/.bash_profile:

export JENV_HOME="${HOME}/.jenv"
eval "$(jenv init -)"
export PATH=${JENV_HOME}/bin:${PATH}

Let’s source our updated ~/.bash_profile and check what versions of Java we have currently:

$ source ~/.bash_profile
$ jenv versions
* system (set by /Users/raph/.jenv/version)

Since we haven’t added any Java environments, jenv is using our system defaults. Let’s add Java 8. Since I have Java 7 installed, I will be adding that as well.

$ ll /Library/Java/JavaVirtualMachines/
total 0
drwxr-xr-x 3 root wheel 102 May 8 23:16 jdk1.7.0_80.jdk
drwxr-xr-x 3 root wheel 102 Oct 15 15:41 jdk1.8.0_144.jdk
$ jenv add /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/
oracle64-1.8.0.144 added
1.8.0.144 added
1.8 added
$ jenv add /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/
oracle64-1.7.0.80 added
1.7.0.80 added
1.7 added
$ jenv versions
* system (set by /Users/raph/.jenv/version)
1.7
1.7.0.80
1.8
1.8.0.144
oracle64-1.7.0.80
oracle64-1.8.0.144

With multiple versions added to jenv, switching between versions at a global, local, or shell level is as easy as specifying the level and version.

$ jenv global oracle64-1.7.0.80
$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
$ jenv global oracle64-1.8.0.144
$ java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

Unlocking the bootloader

The installation of the android-sdk should give us access to all of the Android platform tools. Let’s double check that adb and fastboot is properly installed since those are the two tools we’ll need.

$ adb version
Android Debug Bridge version 1.0.39
Revision 3db08f2c6889-android
Installed as /usr/local/bin/adb
$ ll /usr/local/bin/adb
lrwxr-xr-x 1 raph admin 65 Oct 15 15:37 /usr/local/bin/adb -> /usr/local/Caskroom/android-sdk/3859397,26.0.2/platform-tools/adb
$ fastboot --version
fastboot version 9dc0875966c0-android
Installed as /usr/local/bin/fastboot
$ ll /usr/local/bin/fastboot
lrwxr-xr-x 1 raph admin 70 Oct 15 15:37 /usr/local/bin/fastboot -> /usr/local/Caskroom/android-sdk/3859397,26.0.2/platform-tools/fastboot

Checking the details of the installed tools shows us that brew did in fact install them in its own directory and then created a symlink to the tool in the /usr/local/bin directory. Cool stuff.

Note: unlocking the bootloader will delete all of the data on your phone! Be sure to back up any files that you need beforehand.

On your phone, navigate to Settings > System > About Phone and click on Build number seven times to unlock the Developer options.

Click on Build number seven times to unlock Developer options

Now navigate to Settings > System > Developer options and turn USB debugging on.

Turn USB debugging on in Developer options

Connect your phone to your PC and run the following.

$ adb devices
List of devices attached
HT123456789 device

After verifying that adb recognizes your phone, we’ll reboot into the bootloader.

$ adb reboot bootloader

Your screen should look similar to the following with the exception of the last line since my phone is already unlocked.

Pixel XL Bootloader

Similar to how we verified that adb was able to recognize our phone, we want to do the same with fastboot.

$ fastboot devices
HT123456789 fastboot

Everything looks good, so let’s issue the unlock command and then reboot our device.

$ fastboot flashing unlock
...
OKAY [ 0.050s]
finished. total time: 0.050s
$ fastboot reboot

If all went well, you should see the following warning on your screen during the reboot:

Bootloader warning for unlocked devices

Once your phone boots back up, you will need to go through the initial setup phase again. You will also need to reenable Developer options and USB debugging.

Background information on TWRP and Magisk

TWRP is a custom recovery tool that allows you to backup and restore images of your device as well as flash kernels, ROMs, radio bands, and other tools. With Android being open source, the development community often makes tweaks to stock tools and releases them free-to-flash.

A few benefits of flashing custom tools:

  • Kernels: may provide optimal CPU min/max configurations to make older devices perform faster while also improving battery life.
  • Radio bands: may improve signal quality and provide better GPS triangulation.
  • ROMs: may provide updates faster than the manufacturer or can even provide a completely new experience with custom ROMs.

Magisk is a tool that will provide systemless root to your device.

In the old days, rooting your device meant modifying the /system folder, but since the release of Android Pay, Google has implemented SafetyNet to protect devices from security threats. Previous root methods that touch /system will no longer pass SafetyNet tests, which means you would not be able to use apps that connect to SafetyNet for validation (Android Pay, Pokémon Go, Netflix to name a few). The developer of Magisk was able to circumvent this by creating a systemless root that doesn’t modify the /system folder at all, thus ensuring that your device can still pass SafetyNet.

It makes a lot of sense for Google to take these measures as rooting your device exposes you to a higher level of risk. That said, for those of us who prefer total control over the devices that we own and are comfortable with the associated risk level, root access opens up a lot of options.

I’ll briefly touch on a few root apps that I use personally:

  • Titanium Backup: allows you to backup and restore all applications on your phone. Also gives you the option to freeze a system app. These are apps that come preinstalled on your phone with no option to uninstall. Freezing these apps will essentially ensure that they never run, hiding it from your app drawer and keeping your resources free.
  • Tasker: allows you to create tasks to automate pretty much anything you can think of. I will dive into some of my automated tasks in future posts.
  • Cerberus: an anti-theft app that allows you to remotely control your device. You can enable location tracking, take pictures, record video, start a loud alarm that persists through silent mode, and even disable powering off your device.

All of these benefits do not come without risk. You should always do your due diligence on the developer, permissions granted, known issues, and bugs before flashing any custom tool or root application.

Installing TWRP and Magisk

Download the latest versions of the following:

Connect your Android phone to your PC and transfer the TWRP and Magisk .zip files to your device. No need to transfer the .img file.

Double check that adb recognizes your device and then reboot into the bootloader again.

$ adb devices
List of devices attached
HT123456789 device
$ adb reboot bootloader

Once you are on the bootloader screen, we will double check that fastboot can see our device and then boot the .img file that we saved to our PC earlier.

$ fastboot devices
HT123456789 fastboot
$ fastboot boot twrp-3.1.1-1-fastboot-marlin.img
downloading 'boot.img'...
OKAY [ 0.725s]
booting...
OKAY [ 0.793s]
finished. total time: 1.517s

Our phone should boot into TWRP and we should see the following.

TWRP home screen

Click Install and then navigate to the directory on your device where you saved the TWRP and Magisk .zip files.

We’ll install TWRP first. Click on the TWRP .zip file and then Swipe to confirm flash.

Repeat the same steps to install the Magisk .zip file and then Reboot > System.

You should see two new apps in your app drawer:

  1. Official TWRP App
  2. Magisk Manager

Open the Magisk Manager app and click on Tap to start SafetyNet check to verify that your device can pass validation.

Looks good!

If the install didn’t pan out for you for whatever reason, please check the TWRP and Magisk XDA forums for help. Cheers! 🍺