FileDocCategorySizeDatePackage
SelectServiceHandler.javaAPI DocphoneME MR2 API (J2ME)6637Wed May 02 18:00:32 BST 2007com.sun.kvem.jsr082.bluetooth

SelectServiceHandler.java

/*
 *
 *
 * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */
package com.sun.kvem.jsr082.bluetooth;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import java.util.Hashtable;
import java.util.Vector;

/**
 * This class represents the module which is used by
 * DiscoveryAgent#selectService method implementation.
 *
 */
final class SelectServiceHandler implements DiscoveryListener {

    /** Set to false in RR version - then the javac skip the code. */
    private static final boolean DEBUG = false;
    
    private Vector btDevs;
    private Hashtable btDevsHash;
    private Object btDevsLock = new Object();
    private boolean selectDevDisStarted;
    private boolean selectDevDisStopped;
    private DiscoveryAgentImpl agent;

    /**
     * Constructs <code>SelectServiceHandler</code> for 
     * <code>DiscoveryAgentImpl</code> given.
     *
     * @param agent the discovery agent to create instance for.
     */
    SelectServiceHandler(DiscoveryAgentImpl agent) {
        this.agent = agent;
    }

    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {

        // if this bloototh device was found in preknown or
        // cached devices skips it now.
        if (btDevsHash.put(btDevice, btDevice) == null) {
            btDevs.addElement(btDevice);
        }
    }

    public void inquiryCompleted(int discType) {
        synchronized (btDevsLock) {
            selectDevDisStopped = true;
            btDevsLock.notify();
        }
    }

    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
        throw new RuntimeException("unexpected call");
    }

    public void serviceSearchCompleted(int transID, int respCode) {
        throw new RuntimeException("unexpected call");
    }

    String selectService(UUID uuid, int security, boolean master)
            throws BluetoothStateException {
        if (DEBUG) {
            System.out.println("selectService:");
            System.out.println("\tuuid=" + uuid);
        }
        Vector disDevsVector = null;
        Hashtable disDevsHash = new Hashtable();

        if (uuid == null) {
            throw new NullPointerException("uuid is null");
        }

        // check in CACHED and PREKNOWN devices
        String url = selectFromDevicesList(agent.retrieveDevices(
                DiscoveryAgent.PREKNOWN), uuid, security, master, disDevsHash);

        if (url != null) {
            return url;
        }
        url = selectFromDevicesList(agent.retrieveDevices(
                DiscoveryAgent.CACHED), uuid, security, master, disDevsHash);

        if (url != null) {
            return url;
        }

        // start own device discovery now
        synchronized (btDevsLock) {
            if (selectDevDisStarted) {
                throw new BluetoothStateException(
                        "The previous device discovery is running...");
            }
            selectDevDisStarted = true;
            btDevs = new Vector();
            btDevsHash = disDevsHash;
        }

        try {
            agent.startInquiry(DiscoveryAgent.GIAC, this);
        } catch (BluetoothStateException btse) {
            synchronized (btDevsLock) {
                selectDevDisStarted = false;
                btDevs = null;
                btDevsHash = null;
            }
            throw btse;
        }

        synchronized (btDevsLock) {
            if (!selectDevDisStopped) {
                try {
                    btDevsLock.wait();
                } catch (InterruptedException ie) {
                    // ignore (breake waiting)
                }
                disDevsVector = btDevs;
                btDevs = null;
                btDevsHash = null;
                selectDevDisStarted = false;
                selectDevDisStopped = false;
            }
        }

        for (int i = 0; i < disDevsVector.size(); i++) {
            RemoteDevice btDev = (RemoteDevice) disDevsVector.elementAt(i);
            url = selectService(btDev, uuid, security, master);

            if (url != null) {
                if (DEBUG) {
                    System.out.println("\turl=" + url);
                }
                return url;
            }
        }
        if (DEBUG) {
            System.out.println("\turl=null");
        }
        return null;
    }

    private String selectFromDevicesList(RemoteDevice[] devs, UUID uuid,
            int security, boolean master, Hashtable disDevsHash) {
        if (devs == null) {
            return null;
        }

        for (int i = 0; i < devs.length; i++) {
            if (disDevsHash.put(devs[i], devs[i]) != null) {
                continue;
            }
            String url = selectService(devs[i], uuid, security, master);

            if (url != null) {
                if (DEBUG) {
                    System.out.println("\turl=" + url);
                }
                return url;
            }
        }
        return null;
    }

    private String selectService(RemoteDevice btDev, UUID uuid, int security,
            boolean master) {
        UUID[] uuidSet = new UUID[] {uuid};
        ServiceSelector selector = new ServiceSelector(null, uuidSet, btDev);
        ServiceRecord serRec = selector.getServiceRecord();

        if (serRec == null) {
            return null;
        } else {
            return serRec.getConnectionURL(security, master);
        }
    }
} // end of class 'SelectServiceHandler' definition