All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.shazam.fork.system.adb.Installer Maven / Gradle / Ivy

There is a newer version: 3.18.1
Show newest version
/*
 * Copyright 2014 Shazam Entertainment Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License.
 *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package com.shazam.fork.system.adb;

import com.android.ddmlib.IDevice;
import com.android.ddmlib.InstallException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;

import javax.annotation.Nonnull;

import static java.lang.String.format;

public class Installer {
    private static final Logger logger = LoggerFactory.getLogger(Installer.class);
	private final String applicationPackage;
	private final String instrumentationPackage;
	private final File apk;
	private final File testApk;
    private final boolean autoGrantPermissions;

	public Installer(String applicationPackage,
					 String instrumentationPackage,
					 File apk,
					 File testApk,
					 boolean autoGrantPermissions) {
		this.applicationPackage = applicationPackage;
		this.instrumentationPackage = instrumentationPackage;
		this.apk = apk;
		this.testApk = testApk;
		this.autoGrantPermissions = autoGrantPermissions;
	}

	public void prepareInstallation(IDevice device) {
		reinstall(device, applicationPackage, apk);
		reinstall(device, instrumentationPackage, testApk);
		grantMockLocationInMarshmallow(device, applicationPackage);
	}

	private void reinstall(final IDevice device, final String appPackage, final File appApk) {
		final String message = format("Error while installing %s on %s", appPackage, device.getSerialNumber());
		tryThrice(true, message, () -> {
			try {
				logger.debug("Uninstalling {} from {}", appPackage, device.getSerialNumber());
				device.uninstallPackage(appPackage);
				logger.debug("Installing {} to {}", appPackage, device.getSerialNumber());
				device.installPackage(appApk.getAbsolutePath(), true, optionalAutoGrantPermissionFlag(device));
			} catch (InstallException e) {
				throw new RuntimeException(message, e);
			}
        });
	}

	@Nonnull
	private String optionalAutoGrantPermissionFlag(IDevice device) {
		return isMarshmallowOrMore(device) && autoGrantPermissions ? "-g" : "";
	}

	private boolean isMarshmallowOrMore(@Nonnull IDevice device){
		return device.getVersion().getApiLevel() >= 23;
	}

	private void tryThrice(boolean disaster, String message, Runnable runnable) {
		for (int attempt = 1;; ++attempt) {
			try {
				runnable.run();
				if (attempt > 1) {
                    logger.warn("Success after: " + message);
				}
				return;
			} catch (RuntimeException e) {
                logger.error("Attempt #{} failed: {}", attempt, message);
                if (attempt == 3) {
                    if (disaster) {
                        throw e;
                    }
                    return;
                }
            }
        }
    }

    private void grantMockLocationInMarshmallow(final IDevice device, final String appPackage) {
        if (isMarshmallowOrMore(device)) {
            CollectingShellOutputReceiver receiver = new CollectingShellOutputReceiver();
            String command = " appops set " + appPackage + " android:mock_location allow";
            try {
                device.executeShellCommand(command, receiver);
                logger.debug("When mock location granted for " + appPackage + " :" + receiver.getOutput());
            } catch (Exception e) {
                logger.warn("Error when executing " + command + " on " + device.getSerialNumber(), e);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy