com.android.tools.idea.run.DeviceSelectionUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.android.tools.idea.run.DeviceSelectionUtils.java

Source

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.android.tools.idea.run;

import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Utility methods for selecting a running device.
 */
public class DeviceSelectionUtils {
    @NotNull
    private static final Logger LOG = Logger.getInstance(DeviceSelectionUtils.class);
    // We remember what serials the user uses so we can pre-select them in the manual choosing dialog.
    @NonNls
    private static final String ANDROID_TARGET_DEVICES_PROPERTY = "AndroidTargetDevices";

    /**
     * Returns a compatible, already-running device for launch.
     * If no compatible devices are running, returns an empty list.
     * If exactly one compatible device is running, returns it.
     * If multiple compatible devices are running, prompt the user to select devices.
     * If they select any, return them, but if they do not, return null.
     */
    @Nullable
    public static Collection<IDevice> chooseRunningDevice(@NotNull final AndroidFacet facet,
            @NotNull final Predicate<IDevice> deviceFilter, @NotNull final DeviceCount deviceCount) {
        final Collection<IDevice> compatibleDevices = getAllCompatibleDevices(deviceFilter);

        if (compatibleDevices.size() == 0) {
            return ImmutableList.of();
        } else if (compatibleDevices.size() == 1) {
            return compatibleDevices;
        } else {
            // Ask the user to pick one (or more) of the matching devices.
            final AtomicReference<IDevice[]> devicesRef = new AtomicReference<IDevice[]>();
            ApplicationManager.getApplication().invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    devicesRef.set(chooseDevicesManually(facet, deviceFilter, deviceCount));
                }
            }, ModalityState.defaultModalityState());
            // Return the selected devices, or null if the user cancelled.
            return devicesRef.get().length > 0 ? ImmutableList.copyOf(devicesRef.get()) : null;
        }
    }

    @NotNull
    public static List<IDevice> getAllCompatibleDevices(Predicate<IDevice> deviceFilter) {
        final List<IDevice> compatibleDevices = new ArrayList<IDevice>();
        final AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();

        if (bridge != null) {
            IDevice[] devices = bridge.getDevices();

            for (IDevice device : devices) {
                if (deviceFilter.apply(device)) {
                    compatibleDevices.add(device);
                }
            }
        }
        return compatibleDevices;
    }

    @NotNull
    public static Collection<IDevice> getOnlineDevices(@Nullable Collection<IDevice> devices) {
        if (devices == null) {
            return Collections.emptyList();
        }

        final List<IDevice> online = Lists.newArrayListWithExpectedSize(devices.size());
        for (IDevice device : devices) {
            if (device.isOnline()) {
                online.add(device);
            }
        }
        return online;
    }

    @NotNull
    private static IDevice[] chooseDevicesManually(@NotNull AndroidFacet facet, @NotNull Predicate<IDevice> filter,
            @NotNull DeviceCount deviceCount) {
        final Project project = facet.getModule().getProject();
        String value = PropertiesComponent.getInstance(project).getValue(ANDROID_TARGET_DEVICES_PROPERTY);
        String[] selectedSerials = value != null ? deserialize(value) : null;
        AndroidPlatform platform = facet.getConfiguration().getAndroidPlatform();
        if (platform == null) {
            LOG.error("Android platform not set for module: " + facet.getModule().getName());
            return DeviceChooser.EMPTY_DEVICE_ARRAY;
        }
        DeviceChooserDialog chooser = new DeviceChooserDialog(facet, platform.getTarget(), deviceCount.isMultiple(),
                selectedSerials, filter);
        chooser.show();
        IDevice[] devices = chooser.getSelectedDevices();
        if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE || devices.length == 0) {
            return DeviceChooser.EMPTY_DEVICE_ARRAY;
        }
        PropertiesComponent.getInstance(project).setValue(ANDROID_TARGET_DEVICES_PROPERTY, serialize(devices));
        return devices;
    }

    @NotNull
    public static String serialize(@NotNull IDevice[] devices) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0, n = devices.length; i < n; i++) {
            builder.append(devices[i].getSerialNumber());
            if (i < n - 1) {
                builder.append(' ');
            }
        }
        return builder.toString();
    }

    @NotNull
    private static String[] deserialize(@NotNull String s) {
        return s.split(" ");
    }
}