Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05ff98bb authored by Tao Liejun's avatar Tao Liejun Committed by Nick Pelly
Browse files

Fix minor obex bugs and re-format the comments

re-format comments
move connectible to connectable
remove unnecessary throws
remove not-used function ClientOperation.readResponse()
fix client abort case for PUT
set mOpen for PrivateOutputStream
add to platform.xml
parent c047d683
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -148,5 +148,7 @@
            file="/system/framework/android.test.runner.jar" />
    <library name="com.android.im.plugin"
            file="/system/framework/com.android.im.plugin.jar"/>          
    <library name="javax.obex"
            file="/system/framework/javax.obex.jar"/>

</permissions>
+40 −49
Original line number Diff line number Diff line
@@ -37,50 +37,47 @@ package javax.obex;
 * authentication response headers. When a client or server receives an
 * authentication challenge or authentication response header, the
 * <code>onAuthenticationChallenge()</code> or
 * <code>onAuthenticationResponse()</code> will be called, respectively, by
 * the implementation.
 * <code>onAuthenticationResponse()</code> will be called, respectively, by the
 * implementation.
 * <P>
 * For more information on how the authentication procedure works in OBEX,
 * please review the IrOBEX specification at
 * <A HREF="http://www.irda.org">http://www.irda.org</A>.
 * please review the IrOBEX specification at <A
 * HREF="http://www.irda.org">http://www.irda.org</A>.
 * <P>
 * <STRONG>Authentication Challenges</STRONG>
 * <P>
 * When a client or server receives an authentication challenge header, the
 * <code>onAuthenticationChallenge()</code> method will be invoked by the
 * OBEX API implementation.  The application will then return the user name
 * (if needed) and password via a <code>PasswordAuthentication</code> object.
 * The password in this object is not sent in the authentication response.
 * Instead, the 16-byte challenge received in the authentication challenge is
 * combined with the password returned from the
 * <code>onAuthenticationChallenge()</code> method and passed through the MD5
 * hash algorithm.  The resulting value is sent in the authentication response
 * along with the user name if it was provided.
 * <code>onAuthenticationChallenge()</code> method will be invoked by the OBEX
 * API implementation. The application will then return the user name (if
 * needed) and password via a <code>PasswordAuthentication</code> object. The
 * password in this object is not sent in the authentication response. Instead,
 * the 16-byte challenge received in the authentication challenge is combined
 * with the password returned from the <code>onAuthenticationChallenge()</code>
 * method and passed through the MD5 hash algorithm. The resulting value is sent
 * in the authentication response along with the user name if it was provided.
 * <P>
 * <STRONG>Authentication Responses</STRONG>
 * <P>
 * When a client or server receives an authentication response header, the
 * <code>onAuthenticationResponse()</code> method is invoked by the API
 * implementation with the user name received in the authentication response
 * header.  (The user name will be <code>null</code> if no user name was
 * provided in the authentication response header.)  The application must
 * determine the correct password.  This value should be returned from the
 * <code>onAuthenticationResponse()</code> method.  If the authentication
 * request should fail without the implementation checking the password,
 * <code>null</code> should
 * be returned by the application.  (This is needed for reasons like not
 * recognizing the user name, etc.)  If the returned value is not
 * <code>null</code>, the OBEX API implementation will combine the password
 * header. (The user name will be <code>null</code> if no user name was provided
 * in the authentication response header.) The application must determine the
 * correct password. This value should be returned from the
 * <code>onAuthenticationResponse()</code> method. If the authentication request
 * should fail without the implementation checking the password,
 * <code>null</code> should be returned by the application. (This is needed for
 * reasons like not recognizing the user name, etc.) If the returned value is
 * not <code>null</code>, the OBEX API implementation will combine the password
 * returned from the <code>onAuthenticationResponse()</code> method and
 * challenge sent via the authentication challenge, apply the MD5 hash
 * algorithm, and compare the result to the response hash received in the
 * authentication response header. If the values are not equal, an
 * <code>IOException</code> will be thrown if the client requested authentication.
 * If the server requested authentication, the
 * <code>IOException</code> will be thrown if the client requested
 * authentication. If the server requested authentication, the
 * <code>onAuthenticationFailure()</code> method will be called on the
 * <code>ServerRequestHandler</code> that failed authentication.  The
 * connection is <B>not</B> closed if authentication failed.
 *
 * <code>ServerRequestHandler</code> that failed authentication. The connection
 * is <B>not</B> closed if authentication failed.
 * @hide
 */
public interface Authenticator {
@@ -90,21 +87,16 @@ public interface Authenticator {
     * header. It should respond to the challenge with a
     * <code>PasswordAuthentication</code> that contains the correct user name
     * and password for the challenge.
     *
     * @param description the description of which user name and password
     * should be used; if no description is provided in the authentication
     * challenge or the description is encoded in an encoding scheme that is
     * not supported, an empty string will be provided
     *
     * @param description the description of which user name and password should
     *        be used; if no description is provided in the authentication
     *        challenge or the description is encoded in an encoding scheme that
     *        is not supported, an empty string will be provided
     * @param isUserIdRequired <code>true</code> if the user ID is required;
     *        <code>false</code> if the user ID is not required
     *
     * @param isFullAccess <code>true</code> if full access to the server
     * will be granted; <code>false</code> if read only access will be
     * granted
     *
     * @return a <code>PasswordAuthentication</code> object containing the
     * user name and password used for authentication
     * @param isFullAccess <code>true</code> if full access to the server will
     *        be granted; <code>false</code> if read only access will be granted
     * @return a <code>PasswordAuthentication</code> object containing the user
     *         name and password used for authentication
     */
    PasswordAuthentication onAuthenticationChallenge(String description, boolean isUserIdRequired,
            boolean isFullAccess);
@@ -113,12 +105,11 @@ public interface Authenticator {
     * Called when a client or server receives an authentication response
     * header. This method will provide the user name and expect the correct
     * password to be returned.
     *
     * @param userName the user name provided in the authentication response;
     * may be <code>null</code>
     *
     * @param userName the user name provided in the authentication response; may
     *        be <code>null</code>
     * @return the correct password for the user name provided; if
     * <code>null</code> is returned then the authentication request failed
     *         <code>null</code> is returned then the authentication request
     *         failed
     */
    byte[] onAuthenticationResponse(byte[] userName);
}
+7 −14
Original line number Diff line number Diff line
@@ -37,14 +37,12 @@ import java.io.IOException;
/**
 * This interface defines the methods needed by a parent that uses the
 * PrivateInputStream and PrivateOutputStream objects defined in this package.
 *
 * @hide
 */
public interface BaseStream {

    /**
     * Verifies that this object is still open.
     *
     * @throws IOException if the object is closed
     */
    void ensureOpen() throws IOException;
@@ -52,31 +50,26 @@ public interface BaseStream {
    /**
     * Verifies that additional information may be sent. In other words, the
     * operation is not done.
     *
     * @throws IOException if the operation is completed
     */
    void ensureNotDone() throws IOException;

    /**
     * Continues the operation since there is no data to read.
     *
     * @param sendEmpty <code>true</code> if the operation should send an
     * empty packet or not send anything if there is no data to send
     * @param inStream  <code>true</code> if the stream is input stream or
     * is output stream
     * @param sendEmpty <code>true</code> if the operation should send an empty
     *        packet or not send anything if there is no data to send
     * @param inStream <code>true</code> if the stream is input stream or is
     *        output stream
     * @return <code>true</code> if the operation was completed;
     *         <code>false</code> if no operation took place
     *
     * @throws IOException if an IO error occurs
     */
    boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException;

    /**
     * Called when the output or input stream is closed.
     *
     * @param inStream <code>true</code> if the input stream is closed;
     *        <code>false</code> if the output stream is closed
     *
     * @throws IOException if an IO error occurs
     */
    void streamClosed(boolean inStream) throws IOException;
+41 −132
Original line number Diff line number Diff line
@@ -40,9 +40,8 @@ import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;

/**
 * This class implements the <code>Operation</code> interface.  It will read
 * and write data via puts and gets.
 *
 * This class implements the <code>Operation</code> interface. It will read and
 * write data via puts and gets.
 * @hide
 */
public final class ClientOperation implements Operation, BaseStream {
@@ -79,9 +78,8 @@ public final class ClientOperation implements Operation, BaseStream {
     * @param p the parent to this object
     * @param type <code>true</code> if this is a get request;
     *        <code>false</code. if this is a put request
     * @param headers the headers to set in the initial request
     *
     * @throws IOExcpetion if the an IO error occured
     * @param header the header to set in the initial request
     * @throws IOException if the an IO error occurred
     */
    public ClientOperation(int maxSize, ClientSession p, HeaderSet header, boolean type)
            throws IOException {
@@ -129,17 +127,11 @@ public final class ClientOperation implements Operation, BaseStream {
     * Sends an ABORT message to the server. By calling this method, the
     * corresponding input and output streams will be closed along with this
     * object.
     *
     * @throws IOException if the transaction has already ended or if an
     * OBEX server called this method
     * @throws IOException if the transaction has already ended or if an OBEX
     *         server called this method
     */
    public synchronized void abort() throws IOException {
        ensureOpen();
        // need check again .
        //	if(isDone) {
        //	     throw new IOException("Operation has already ended");
        //	}

        //no compatible with sun-ri
        if ((mOperationDone) && (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE)) {
            throw new IOException("Operation has already ended");
@@ -165,15 +157,14 @@ public final class ClientOperation implements Operation, BaseStream {
    }

    /**
     * Retrieves the response code retrieved from the server.  Response codes
     * are defined in the <code>ResponseCodes</code> interface.
     *
     * Retrieves the response code retrieved from the server. Response codes are
     * defined in the <code>ResponseCodes</code> interface.
     * @return the response code retrieved from the server
     *
     * @throws IOException if an error occurred in the transport layer during
     * the transaction; if this method is called on a <code>HeaderSet</code>
     * object created by calling <code>createHeaderSet</code> in a
     * <code>ClientSession</code> object
     *         the transaction; if this method is called on a
     *         <code>HeaderSet</code> object created by calling
     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
     *         object
     */
    public synchronized int getResponseCode() throws IOException {
        //avoid dup validateConnection
@@ -187,7 +178,6 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * This method will always return <code>null</code>
     *
     * @return <code>null</code>
     */
    public String getEncoding() {
@@ -198,7 +188,6 @@ public final class ClientOperation implements Operation, BaseStream {
     * Returns the type of content that the resource connected to is providing.
     * E.g. if the connection is via HTTP, then the value of the content-type
     * header field is returned.
     *
     * @return the content type of the resource that the URL references, or
     *         <code>null</code> if not known
     */
@@ -212,9 +201,8 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Returns the length of the content which is being provided. E.g. if the
     * connection is via HTTP, then the value of the content-length header
     * field is returned.
     *
     * connection is via HTTP, then the value of the content-length header field
     * is returned.
     * @return the content length of the resource that this connection's URL
     *         references, or -1 if the content length is not known
     */
@@ -234,9 +222,7 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Open and return an input stream for a connection.
     *
     * @return an input stream
     *
     * @throws IOException if an I/O error occurs
     */
    public InputStream openInputStream() throws IOException {
@@ -259,11 +245,9 @@ public final class ClientOperation implements Operation, BaseStream {
        return mPrivateInput;
    }

    /**8
    /**
     * Open and return a data input stream for a connection.
     *
     * @return an input stream
     *
     * @throws IOException if an I/O error occurs
     */
    public DataInputStream openDataInputStream() throws IOException {
@@ -272,9 +256,7 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Open and return an output stream for a connection.
     *
     * @return an output stream
     *
     * @throws IOException if an I/O error occurs
     */
    public OutputStream openOutputStream() throws IOException {
@@ -301,9 +283,7 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Open and return a data output stream for a connection.
     *
     * @return an output stream
     *
     * @throws IOException if an I/O error occurs
     */
    public DataOutputStream openDataOutputStream() throws IOException {
@@ -312,7 +292,6 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Closes the connection and ends the transaction
     *
     * @throws IOException if the operation has already ended or is closed
     */
    public void close() throws IOException {
@@ -324,11 +303,9 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Returns the headers that have been received during the operation.
     * Modifying the object returned has no effect on the headers that are
     * sent or retrieved.
     *
     * Modifying the object returned has no effect on the headers that are sent
     * or retrieved.
     * @return the headers received during this <code>Operation</code>
     *
     * @throws IOException if this <code>Operation</code> has been closed
     */
    public HeaderSet getReceivedHeader() throws IOException {
@@ -340,15 +317,11 @@ public final class ClientOperation implements Operation, BaseStream {
    /**
     * Specifies the headers that should be sent in the next OBEX message that
     * is sent.
     *
     * @param headers the headers to send in the next message
     *
     * @throws IOException  if this <code>Operation</code> has been closed
     * or the transaction has ended and no further messages will be exchanged
     *
     * @throws IOException if this <code>Operation</code> has been closed or the
     *         transaction has ended and no further messages will be exchanged
     * @throws IllegalArgumentException if <code>headers</code> was not created
     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
     *
     * @throws NullPointerException if <code>headers</code> is <code>null</code>
     */
    public void sendHeaders(HeaderSet headers) throws IOException {
@@ -369,63 +342,9 @@ public final class ClientOperation implements Operation, BaseStream {
        }
    }

    /**
     * Reads a response from the server.  It will populate the appropriate body
     * and headers.
     *
     * @return <code>true</code> if the transaction should end;
     * <code>false</code> if the transaction should not end
     *
     * @throws IOException if an IO error occurred
     */
    /*
    private boolean readResponse() throws IOException {
        mReplyHeader.responseCode = mInput.read();
        int packetLength = mInput.read();
        packetLength = (packetLength << 8) + mInput.read();

        if (packetLength > ObexHelper.MAX_PACKET_SIZE_INT) {
            if (mExceptionMessage != null) {
                abort();
            }
            throw new IOException("Received a packet that was too big");
        }

        if (packetLength > ObexHelper.BASE_PACKET_LENGTH) {
            int dataLength = packetLength - ObexHelper.BASE_PACKET_LENGTH;
            byte[] data = new byte[dataLength];
            int readLength = mInput.read(data);
            if (readLength != dataLength) {
                throw new IOException("Received a packet without data as decalred length");
            }
            byte[] body = ObexHelper.updateHeaderSet(mReplyHeader, data);

            if (body != null) {
                mPrivateInput.writeBytes(body, 1);

                /*
                 * Determine if a body (0x48) header or an end of body (0x49)
                 * was received.  If we received an end of body and
                 * a response code of OBEX_HTTP_OK, then the operation should
                 * end.
                 *
                if ((body[0] == 0x49) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_OK)) {
                    return false;
                }
            }
        }

        if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
            return true;
        } else {
            return false;
        }
    }
    */
    /**
     * Verifies that additional information may be sent. In other words, the
     * operation is not done.
     *
     * @throws IOException if the operation is completed
     */
    public void ensureNotDone() throws IOException {
@@ -436,7 +355,6 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Verifies that the connection is open and no exceptions should be thrown.
     *
     * @throws IOException if an exception needs to be thrown
     */
    public void ensureOpen() throws IOException {
@@ -452,7 +370,6 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Verifies that the connection is open and the proper data has been read.
     *
     * @throws IOException if an IO error occurs
     */
    private void validateConnection() throws IOException {
@@ -466,15 +383,12 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Sends a request to the client of the specified type
     *
     * @param response the response code to send back to the client
     *
     * @param opCode the request code to send to the client
     * @return <code>true</code> if there is more data to send;
     *         <code>false</code> if there is no more data to send
     *
     * @throws IOException if an IO error occurs
     */
    private boolean sendRequest(int type) throws IOException {
    private boolean sendRequest(int opCode) throws IOException {
        boolean returnValue = false;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int bodyLength = -1;
@@ -519,7 +433,7 @@ public final class ClientOperation implements Operation, BaseStream {

                byte[] sendHeader = new byte[end - start];
                System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length);
                if (!mParent.sendRequest(type, sendHeader, mReplyHeader, mPrivateInput)) {
                if (!mParent.sendRequest(opCode, sendHeader, mReplyHeader, mPrivateInput)) {
                    return false;
                }

@@ -559,7 +473,7 @@ public final class ClientOperation implements Operation, BaseStream {
             * (End of Body) otherwise, we need to send 0x48 (Body)
             */
            if ((mPrivateOutput.isClosed()) && (!returnValue) && (!mEndOfBodySent)
                    && ((type & 0x80) != 0)) {
                    && ((opCode & 0x80) != 0)) {
                out.write(0x49);
                mEndOfBodySent = true;
            } else {
@@ -577,7 +491,7 @@ public final class ClientOperation implements Operation, BaseStream {

        if (mPrivateOutputOpen && bodyLength <= 0 && !mEndOfBodySent) {
            // only 0x82 or 0x83 can send 0x49
            if ((type & 0x80) == 0) {
            if ((opCode & 0x80) == 0) {
                out.write(0x48);
            } else {
                out.write(0x49);
@@ -591,13 +505,13 @@ public final class ClientOperation implements Operation, BaseStream {
        }

        if (out.size() == 0) {
            if (!mParent.sendRequest(type, null, mReplyHeader, mPrivateInput)) {
            if (!mParent.sendRequest(opCode, null, mReplyHeader, mPrivateInput)) {
                return false;
            }
            return returnValue;
        }
        if ((out.size() > 0)
                && (!mParent.sendRequest(type, out.toByteArray(), mReplyHeader, mPrivateInput))) {
                && (!mParent.sendRequest(opCode, out.toByteArray(), mReplyHeader, mPrivateInput))) {
            return false;
        }

@@ -613,7 +527,6 @@ public final class ClientOperation implements Operation, BaseStream {
     * This method starts the processing thread results. It will send the
     * initial request. If the response takes more then one packet, a thread
     * will be started to handle additional requests
     *
     * @throws IOException if an IO error occurs
     */
    private synchronized void startProcessing() throws IOException {
@@ -659,11 +572,10 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Continues the operation since there is no data to read.
     *
     * @param sendEmpty <code>true</code> if the operation should send an
     * empty packet or not send anything if there is no data to send
     * @param inStream  <code>true</code> if the stream is input stream or
     * is output stream
     * @param sendEmpty <code>true</code> if the operation should send an empty
     *        packet or not send anything if there is no data to send
     * @param inStream <code>true</code> if the stream is input stream or is
     *        output stream
     * @throws IOException if an IO error occurs
     */
    public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
@@ -717,10 +629,8 @@ public final class ClientOperation implements Operation, BaseStream {

    /**
     * Called when the output or input stream is closed.
     *
     * @param inStream <code>true</code> if the input stream is closed;
     *        <code>false</code> if the output stream is closed
     *
     * @throws IOException if an IO error occurs
     */
    public void streamClosed(boolean inStream) throws IOException {
@@ -804,7 +714,6 @@ public final class ClientOperation implements Operation, BaseStream {
                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
                    mOperationDone = true;
                }

            }
        }
    }
+12 −25
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import java.io.OutputStream;

/**
 * This class in an implementation of the OBEX ClientSession.
 *
 * @hide
 */
public final class ClientSession extends ObexSession {
@@ -365,7 +364,6 @@ public final class ClientSession extends ObexSession {

    /**
     * Verifies that the connection is open.
     *
     * @throws IOException if the connection is closed
     */
    public synchronized void ensureOpen() throws IOException {
@@ -375,9 +373,8 @@ public final class ClientSession extends ObexSession {
    }

    /**
     * Set request inactive.
     * Allows Put and get operation objects to tell this object when they are
     * done.
     * Set request inactive. Allows Put and get operation objects to tell this
     * object when they are done.
     */
    /*package*/synchronized void setRequestInactive() {
        mRequestActive = false;
@@ -396,26 +393,16 @@ public final class ClientSession extends ObexSession {

    /**
     * Sends a standard request to the client. It will then wait for the reply
     * and update the header set object provided.  If any authentication
     * headers (i.e. authentication challenge or authentication response) are
     * received, they will be processed.
     *
     * and update the header set object provided. If any authentication headers
     * (i.e. authentication challenge or authentication response) are received,
     * they will be processed.
     * @param opCode the type of request to send to the client
     *
     * @param head the headers to send to the server
     *
     * @param challenge the nonce that was sent in the authentication
     * challenge header located in <code>head</code>; <code>null</code>
     * if no authentication header is included in <code>head</code>
     *
     * @param head the headers to send to the client
     * @param header the header object to update with the response
     *
     * @param input the input stream used by the Operation object; null if this
     * is called on a CONNECT, SETPATH or DISCONNECT
     *
     * return <code>true</code> if the operation completed successfully;
     * @param privateInput the input stream used by the Operation object; null
     *        if this is called on a CONNECT, SETPATH or DISCONNECT return
     *        <code>true</code> if the operation completed successfully;
     *        <code>false</code> if an authentication response failed to pass
     *
     * @throws IOException if an IO error occurs
     */
    public boolean sendRequest(int opCode, byte[] head, HeaderSet header,
Loading