Skip to content

Instantly share code, notes, and snippets.

@ppoffice
Last active October 28, 2024 13:22
Show Gist options
  • Save ppoffice/9ce9790708eeabbec1281467e25139e4 to your computer and use it in GitHub Desktop.
Save ppoffice/9ce9790708eeabbec1281467e25139e4 to your computer and use it in GitHub Desktop.
A step by step guide to upgrade webview on an old Android Emulator

Tools

  1. emulator (30.3.5) (via Android SDK)
  2. adb (30.0.5) (via Android SDK)
  3. apktool (2.5.0) and Java runtime
  4. zip (3.0)
  5. unzip (6.0)

Make sure you have JAVA_HOME and ANDROID_HOME environment variables correctly set.

Steps

  1. Create a new Android Virtual Device (AVD) using Android Studio or avdmanager. Here, I created an Android 5.0 device with the following system image:

    Path                                        | Version | Description                                | Location
    system-images;android-21;google_apis;x86_64 | 32      | Google APIs Intel x86 Atom_64 System Image | system-images/android-21/google_apis/x86_64/

    The AVD name is

    $ emulator -list-avds
    Pixel_2_API_21
  2. Boot the AVD and make its system partition writable:

    $ $ANDROID_HOME/tools/emulator @Pixel_2_API_21 -writable-system

    And the AVD starts, remount its system partition using adb:

    $ $ANDROID_HOME/platform-tools/adb remount
  3. Download the Android System Webview of your desired version from the internet. For example, you may use Android System WebView 88.0.4324.93 (x86 + x86_64) (Android 5.0+) from apkmirror.com. The package ID is com.google.android.webview, which is different from the default system webview (com.android.webview). Also, make sure your package has the same ABI as your AVD.

  4. Extract the webview package using unzip and push it and the native libraries to the system partition of your AVD:

    $ unzip <path/to/your/webview.apk>
    $ $ANDROID_HOME/platform-tools/adb shell mkdir /system/app/ChromiumWebview
    $ $ANDROID_HOME/platform-tools/adb push <path/to/your/webview.apk> /system/app/ChromiumWebview/webview.apk
    $ $ANDROID_HOME/platform-tools/adb push <path/to/your/extracted/webview.apk>/lib /system/app/ChromiumWebview/

    After this step is done, you should have the following new files in your AVD:

    $ANDROID_HOME/platform-tools/adb shell ls -lR /system/app/ChromiumWebview/lib                                                            ✔ 
    
    /system/app/ChromiumWebview/lib:
    drwxr-xr-x root     root              2021-01-27 00:36 x86
    drwxr-xr-x root     root              2021-01-27 00:36 x86_64
    
    /system/app/ChromiumWebview/lib/x86:
    -rw-r--r-- root     root        43360 1979-12-31 00:00 libchromium_android_linker.so
    -rw-r--r-- root     root         3680 1979-12-31 00:00 libcrashpad_handler_trampoline.so
    -rw-r--r-- root     root     78167008 1979-12-31 00:00 libwebviewchromium.so
    
    /system/app/ChromiumWebview/lib/x86_64:
    -rw-r--r-- root     root        44896 1979-12-31 00:00 libchromium_android_linker.so
    -rw-r--r-- root     root         5104 1979-12-31 00:00 libcrashpad_handler_trampoline.so
    -rw-r--r-- root     root     78545528 1979-12-31 00:00 libwebviewchromium.so
  5. Restart Android services to let the Package Manager pick up our new webview package:

    $ $ANDROID_HOME/platform-tools/adb shell stop
    $ $ANDROID_HOME/platform-tools/adb shell start
    $ $ANDROID_HOME/platform-tools/adb shell pm list packages | grep webview
    package:com.android.webview           --> the built-in and outdated webview
    package:com.google.android.webview    --> our new webview
  6. Check if the package is registered with the Package Manager. Make sure codePath, nativeLibraryPath, and primaryCpuAbi are correct:

    $ $ANDROID_HOME/platform-tools/adb shell cat /data/system/packages.xml | grep com.google.android.webview
    <package name="com.google.android.webview" codePath="/system/app/ChromiumWebview" nativeLibraryPath="/system/app/ChromiumWebview/lib" primaryCpuAbi="x86_64" secondaryCpuAbi="x86" flags="...
  7. As the default webview package name used by the Android OS is hard-coded in older Android OSes (https://android.stackexchange.com/a/139415), you need to modify the Android framework to use the new package name. First, pull framework-res.apk from your AVD and decompile it using apktool:

    $ $ANDROID_HOME/platform-tools/adb pull /system/framework/framework-res.apk
    $ apktool d framework-res.apk
  8. Update the <path/to/extracted/framework-res.apk>/res/values/strings.xml file to use your new system webview package name:

    --- res/values/strings.xml	2021-01-27 00:53:05.000000000 -0500
    +++ res/values/strings.xml	2021-01-27 00:54:38.000000000 -0500
    @@ -70,7 +70,7 @@
         <string name="config_appsAuthorizedForSharedAccounts">;com.android.settings;</string>
         <string name="config_defaultNetworkScorerPackageName" />
         <string name="config_persistentDataPackageName" />
    -    <string name="config_webViewPackageName">com.android.webview</string>
    +    <string name="config_webViewPackageName">com.google.android.webview</string>
         <item type="string" name="timepicker_circle_radius_multiplier">0.82</item>
         <item type="string" name="timepicker_circle_radius_multiplier_24HourMode">0.85</item>
         <item type="string" name="timepicker_selection_radius_multiplier">0.16</item>
  9. Repack framework-res.apk using apktool.

    $ apktool b <path/to/extracted/framework-res.apk>

    There might be a few errors you need to fix before the package can be repacked. For example, if you encountered the following error:

    Error: String types not allowed (at 'APKTOOL_DUMMY_34e' with value '').
    

    you should replace <drawable name="APKTOOL_DUMMY_..." /> with <item type="drawable" name="APKTOOL_DUMMY_..." /> in the <path/to/extracted/framework-res.apk>/res/values-nodpi-v4/drawables.xml file and retry.

  10. The repacked framework-res.apk is placed under <path/to/extracted/framework-res.apk>/dist. Extract the resources.arsc file from it and merge it to the original framework-res.apk:

    $ unzip <path/to/extracted/framework-res.apk>/dist/framework-res.apk resources.arsc -d .
    $ zip -0 <path/to/original/framework-res.apk> resources.arsc

    The original framework-res.apk you pulled from your AVD is now updated.

  11. Next, replace the framework-res.apk in your AVD with our updated (merged) framework-res.apk from last step and reboot device:

    $ $ANDROID_HOME/platform-tools/adb push <path/to/original/framework-res.apk> /system/framework/framework-res.apk
    $ $ANDROID_HOME/platform-tools/adb reboot
  12. Finally, check if the webview is switched to the new one:

    Screen Shot 2021-01-27 at 1 22 05 AM
@atilaahmettaner
Copy link

To upgrade the Android WebView version, I downloaded the Chrome APK within Android using the terminal. This approach allows updating the WebView component without modifying the system files directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment