remove_preinstalled_webview.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env vpython3
  2. #
  3. # Copyright 2018 The Chromium Authors. All rights reserved.
  4. # Use of this source code is governed by a BSD-style license that can be
  5. # found in the LICENSE file.
  6. """Removes the preinstalled WebView on a device to avoid signature mismatches.
  7. This should only be used by developers. This script will fail on actual user
  8. devices (and this configuration is not recommended for user devices).
  9. The recommended development configuration for Googlers is to satisfy all of the
  10. below:
  11. 1. The device has a Google-provided image.
  12. 2. The device does not have an image based on AOSP.
  13. 3. Set `use_signing_keys = true` in GN args.
  14. If any of the above are not satisfied (or if you're external to Google), you can
  15. use this script to remove the system-image WebView on your device, which will
  16. allow you to install a local WebView build without triggering signature
  17. mismatches (which would otherwise block installing the APK).
  18. After running this script, you should be able to build and install
  19. system_webview_apk.
  20. * If your device does *not* have an AOSP-based image, you will need to set
  21. `system_webview_package_name = "com.google.android.webview"` in GN args.
  22. """
  23. from __future__ import print_function
  24. import argparse
  25. import logging
  26. import os
  27. import sys
  28. sys.path.append(os.path.join(
  29. os.path.dirname(__file__), os.pardir, os.pardir, 'build', 'android'))
  30. # pylint: disable=wrong-import-position,import-error
  31. import devil_chromium
  32. from devil.android import device_errors
  33. from devil.android import device_utils
  34. from devil.android.sdk import keyevent
  35. from devil.android.tools import script_common
  36. from devil.android.tools import system_app
  37. from devil.utils import logging_common
  38. WEBVIEW_PACKAGES = ['com.android.webview', 'com.google.android.webview']
  39. def _UnlockDevice(device):
  40. device.SendKeyEvent(keyevent.KEYCODE_MENU)
  41. def UninstallWebViewSystemImages(device):
  42. """Uninstalls system images for known WebView packages."""
  43. print('Removing system images from %s...' % device.serial)
  44. system_app.RemoveSystemApps(device, WEBVIEW_PACKAGES)
  45. _UnlockDevice(device)
  46. def UninstallWebViewUpdates(device):
  47. """Uninstalls updates for WebView packages, if updates exist."""
  48. print('Uninstalling updates from %s...' % device.serial)
  49. for webview_package in WEBVIEW_PACKAGES:
  50. try:
  51. device.Uninstall(webview_package)
  52. except device_errors.AdbCommandFailedError:
  53. # This can happen if the app is on the system image but there are no
  54. # updates installed on top of that.
  55. logging.info('No update to uninstall for %s on %s', webview_package,
  56. device.serial)
  57. def CheckWebViewIsUninstalled(device):
  58. """Throws if WebView is still installed."""
  59. for webview_package in WEBVIEW_PACKAGES:
  60. if device.IsApplicationInstalled(webview_package):
  61. raise device_errors.CommandFailedError(
  62. '{} is still installed on the device'.format(webview_package),
  63. device)
  64. def RemovePreinstalledWebViews(device):
  65. device.EnableRoot()
  66. UninstallWebViewUpdates(device)
  67. try:
  68. UninstallWebViewSystemImages(device)
  69. CheckWebViewIsUninstalled(device)
  70. except device_errors.CommandFailedError:
  71. if device.is_emulator:
  72. # Point the user to documentation, since there's a good chance they can
  73. # workaround this. Use lots of newlines to make sure this message doesn't
  74. # get lost.
  75. logging.error('Did you start the emulator with "-writable-system?"\n'
  76. 'See https://chromium.googlesource.com/chromium/src/+/'
  77. 'main/docs/android_emulator.md#writable-system-partition'
  78. '\n')
  79. raise
  80. device.SetWebViewFallbackLogic(False) # Allow standalone WebView on N+
  81. def main():
  82. parser = argparse.ArgumentParser(description="""
  83. Removes the preinstalled WebView APKs to avoid signature mismatches during
  84. development.
  85. """)
  86. script_common.AddEnvironmentArguments(parser)
  87. script_common.AddDeviceArguments(parser)
  88. logging_common.AddLoggingArguments(parser)
  89. args = parser.parse_args()
  90. logging_common.InitializeLogging(args)
  91. devil_chromium.Initialize(adb_path=args.adb_path)
  92. devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices)
  93. device_utils.DeviceUtils.parallel(devices).pMap(RemovePreinstalledWebViews)
  94. if __name__ == '__main__':
  95. main()