google / bundletool

Bundletool is a command-line tool to manipulate Android App Bundles
https://g.co/androidappbundle
Apache License 2.0
3.52k stars 385 forks source link

Add a possibility to automatically grant permissions upon apks install #246

Closed mykola-mokhnach closed 3 years ago

mykola-mokhnach commented 3 years ago

Is your feature request related to a problem? Please describe. Currently it is not possible to install an apks and at the same time grant all permissions to it, although vanilla adb does support such feature by adding -g command line option

Describe the solution you'd like Please add an additional flag to the install-apks command, which would allow to grant all permissions to the installed app automatically

Describe alternatives you've considered It is possible to grant permissions using pm grant-permission utility after the app is installed, although it does not support granting multiple permissions at once, which is a great time-eater for automated tests. Also, it is necessary to fetch app identifier for that, which is an additional time-wasting step.

Additional context None

ymakhno commented 3 years ago

Consider extract-apks command which allows to extract APKs that should be installed on the concrete device and next use adb install-multiple to install splits on the device.

We don't have a goal to have flag parity with adb, you are free to use vanilla adb if your use case requires this.

mykola-mokhnach commented 3 years ago

We just wanted to integrate the tool with Appium. Basically it was working like that previously, but a new feature was added recently: the --local-testing flag. To support that feature we'd basically need to completely reimplement all the functionality of bundletool in nodejs. See https://github.com/appium/appium/issues/15887 for more details. It is sad to see that Google does not support open source projects.

ymakhno commented 3 years ago

Got it. The main problem for this feature is bundletool doesn't use adb directly we work through ddmlib - java library to communicate with device.

Under the hood ddmlib uses pm install for standalone APKs and pm install-create for splits. Particularly we will have to do the same, I mean invoke pm grant-permission but inside bundletool if we want to implement this feature.

If you want to use advanced adb features, what I can recommend is to use extract-apks command with --include-metadata flag. In this mode the command will produce you metadata.json with all information about extracted splits, like:

{
  "apks": [
     { "path": "base.apk", "deliveryType": "INSTALL_TIME" },  
     { "path": "module1.apk", "deliveryType": "ON_DEMAND" },
     { "path": "module2.apk", "deliveryType": "FAST_FOLLOW" }
  ],
  "localTestingInfo": {
    "localTestingDir": "<path on device where to put splits>"
  }
}

Next you can take this metadata iterate over apks list and include apk into adb install-multiple command if it has INSTALL_TIME delivery type or push it to directory specified in localTestingInfo.localTestingDir otherwise.

Also please note that localTestingInfo is set only for .apks file which was built with build-apks --local-testing. If it is not included you have to decide what to do with ON_DEMAND, FAST_FOLLOW split - install them or not.

mykola-mokhnach commented 3 years ago

Under the hood ddmlib uses pm install for standalone APKs and pm install-create for splits. Particularly we will have to do the same, I mean invoke pm grant-permission but inside bundletool if we want to implement this feature.

I assume this is not really necessary. ddmlib provides installPackage method, which accepts extraArgs parameter. And where we could potentially pass -g as this is a natively supported pm install argument, at least since API 23:

Maybe I'm wrong, since I'm not a great expert in the Android source code, but I believe there must be a simpler way to support this feature using ddmlib. Basically, it's just about adding one more argument (-g) into https://github.com/google/bundletool/blob/7e12a2401715abdae9ac696c81f549c81fabe08e/src/main/java/com/android/tools/build/bundletool/device/DdmlibDevice.java#L129 same way -d and -t have been already added there, but we'd need to also probably verify the target device's API level, because this flag would be rejected for <23.