/* * Software Name : ATK * * Copyright (C) 2007 - 2012 France Télécom * * 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. * * ------------------------------------------------------------------ * File Name : AutomaticPhoneDetection.java * * Created : 30/10/2009 * Author(s) : Yvain Leyral */ package com.orange.atk.phone.detection; import com.orange.atk.phone.DefaultPhone; import com.orange.atk.phone.PhoneInterface; import com.orange.atk.phone.Plugin; import com.orange.atk.phone.PluginManager; import com.orange.atk.phone.android.AndroidPhone; import com.orange.atk.platform.Platform; import org.apache.log4j.Logger; import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; public class AutomaticPhoneDetection { //singleton pattern private PhoneInterface selectedPhone= null; private List<PhoneInterface> connectedDevices; private DeviceDetectionThread deviceDetectionThread; private List<DeviceDetectionListener> deviceDetectionListeners = new ArrayList<DeviceDetectionListener>(); private static AutomaticPhoneDetection instance=null; private boolean launchThread = true; public static AutomaticPhoneDetection getInstance(){ return AutomaticPhoneDetection.getInstance(true); } public static AutomaticPhoneDetection getInstance(boolean launchThread){ if(instance ==null) { instance = new AutomaticPhoneDetection(launchThread); try { ClassLoader cl = ClassLoader.getSystemClassLoader(); URL[] urls = ((URLClassLoader)cl).getURLs(); for(URL url: urls){ Logger.getLogger("AutomaticPhoneDetection").info(url.getFile()); } String currentDir = new File(".").getAbsolutePath(); Logger.getLogger("AutomaticPhoneDetection").info("currentDir="+currentDir); File folder = new File("./plugin");//here to ease launching via eclipse File[] listOfFiles = folder.listFiles(); if(listOfFiles!=null){ for (int i = 0; i < listOfFiles.length; i++) { if (listOfFiles[i].isFile()) { String filename=listOfFiles[i].getName(); if(filename.endsWith(".jar")){ Logger.getLogger("AutomaticPhoneDetection").info(("Filename " + filename)); String name = filename.substring(0, filename.lastIndexOf('.')); Logger.getLogger("AutomaticPhoneDetection").info(("File " + name)); String classname="com.orange.atk.phone."+name+"."+name.substring(0,1).toUpperCase()+name.substring(1).toLowerCase()+"Plugin"; Logger.getLogger("AutomaticPhoneDetection").info(("Loading " + classname)); Class.forName(classname); }else{ Logger.getLogger("AutomaticPhoneDetection").info(("skipping " + filename)); } } else if (listOfFiles[i].isDirectory()) { Logger.getLogger("AutomaticPhoneDetection").info(("Directory " + listOfFiles[i].getName())); } } } else { Class.forName("com.orange.atk.phone.android.AndroidPlugin"); } } catch (ClassNotFoundException e) { Logger.getLogger("AutomaticPhoneDetection").error("Unable to load plugin"); } } return instance; } //default constructor private AutomaticPhoneDetection(boolean launchThread) { if (launchThread) { deviceDetectionThread = new DeviceDetectionThread(); deviceDetectionThread.start(); } connectedDevices = new ArrayList<PhoneInterface>(); } public void addDeviceDetectionListener(DeviceDetectionListener listener) { deviceDetectionListeners.add(listener); } public void pauseDetection() { if(deviceDetectionThread!=null){ deviceDetectionThread.pauseDetection(); } } public void resumeDetection() { if(deviceDetectionThread!=null){ deviceDetectionThread.resumeDetection(); } } public void stopDetection(DeviceDetectionListener listener) { deviceDetectionListeners.remove(listener); if (deviceDetectionListeners.size()<=1){ deviceDetectionThread.exit(); close(); } } /** * Fabric which return the phone currently connected to the PC * @return phoneInterface. It allows communicate with the phone detected. */ public PhoneInterface getDevice() { if (selectedPhone==null) return new DefaultPhone(); return selectedPhone; } public List<PhoneInterface> getDevices(){ synchronized (connectedDevices) { List<PhoneInterface> connectedEnabledDevices = new ArrayList<PhoneInterface>(); for (int i=0; i<connectedDevices.size(); i++) { if (!connectedDevices.get(i).isDisabledPhone()) { connectedEnabledDevices.add(connectedDevices.get(i)); } } return connectedEnabledDevices; } } public void setSelectedDevice(PhoneInterface phone) { if (phone != selectedPhone) { selectedPhone = phone; for (int i=0; i<deviceDetectionListeners.size(); i++) { deviceDetectionListeners.get(i).deviceSelectedChanged(); } } } @SuppressWarnings("unchecked") public void checkDevices() { boolean changed = false; List<PhoneInterface> newConnectedDevices = new ArrayList<PhoneInterface>(); List<Plugin> plugins = PluginManager.getAll(); for (int j=0; j<plugins.size(); j++) { //Logger.getLogger(this.getClass()).info("plugin "+plugins.get(j).getName()); changed=changed || plugins.get(j).checkDevices(connectedDevices,newConnectedDevices); } synchronized(connectedDevices) { // the devices not present in newConnectedDevices are the one that have been disconnected for (int i=connectedDevices.size()-1; i>=0; i--) { PhoneInterface phone = connectedDevices.get(i); if (!newConnectedDevices.contains(phone)) { if (phone.getCnxStatus()!=PhoneInterface.CNX_STATUS_DISCONNECTED) { phone.setCnxStatus(PhoneInterface.CNX_STATUS_DISCONNECTED); if (phone instanceof AndroidPhone) { if (!((AndroidPhone)phone).isDisabledPhone()) changed = true; } else changed = true; } if (phone.isInRecordingMode()) phone.stopRecordingMode(); if (phone.isInTestingMode()) phone.stopTestingMode(); if (selectedPhone != phone) { connectedDevices.remove(phone); if (phone instanceof AndroidPhone) { if (!((AndroidPhone)phone).isDisabledPhone()) changed = true; } else changed = true; } } else newConnectedDevices.remove(phone); } // add the new device connected to the list for (int i=0; i<newConnectedDevices.size(); i++) { PhoneInterface phone = newConnectedDevices.get(i); connectedDevices.add(phone); } } if (changed) notifyDevicesConnectedChanged(); } public void notifyDevicesConnectedChanged() { for (int i=0; i<deviceDetectionListeners.size(); i++) { deviceDetectionListeners.get(i).devicesConnectedChanged(); } } /** * Detect if actual phone is a nokia phone * @return true if phone connected is a nokia. */ public Boolean isNokia(){ //update device getDevice(); if (selectedPhone!=null) return (selectedPhone.getType() == PhoneInterface.TYPE_S60) ; else return false; } /** * Search the config file path of the phone in parameters. * prefer use {@link #getxmlfilepath()}. * * @return the config file path */ public String getxmlfilepath() { String JATKpath = Platform.getInstance().getJATKPath(); String xmlconfilepath = JATKpath+Platform.FILE_SEPARATOR+"ConfigFiles"+Platform.FILE_SEPARATOR; // Test to determine which config file to use PhoneInterface phone = AutomaticPhoneDetection.getInstance().getDevice(); if (phone != null) { xmlconfilepath += phone.getConfigFile(); } return xmlconfilepath; } /** * close all fabric (like androidDebugBridge) */ private void close() { List<Plugin> plugins = PluginManager.getAll(); for (int j=0; j<plugins.size(); j++) { Logger.getLogger(this.getClass()).info("closing plugin "+plugins.get(j).getName()); plugins.get(j).close(); } } }