/* * Copyright (C) 2015 Samsung System LSI * 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.bluetooth; import java.io.IOException; import javax.obex.HeaderSet; import javax.obex.ServerRequestHandler; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.os.Handler.Callback; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.util.Log; /** * A simple ObexServer used to handle connection rejection in two cases: * - A profile cannot handle a new connection, as it is already connected to another device. * - The user rejected access to the resources needed by the profile. * * Will reject the OBEX connection, start a timer, and at timeout close the socket. */ public class ObexRejectServer extends ServerRequestHandler implements Callback { private static final String TAG = "ObexRejectServer"; private static final boolean V = true; private final int mResult; private final HandlerThread mHandlerThread; private final Handler mMessageHandler; private final static int MSG_ID_TIMEOUT = 0x01; private final static int TIMEOUT_VALUE = 5*1000; // ms private final BluetoothSocket mSocket; /** * @param result the ResponseCodes.OBEX_HTTP_ code to respond to an incoming connect request. */ public ObexRejectServer(int result, BluetoothSocket socket) { super(); mResult = result; mSocket = socket; mHandlerThread = new HandlerThread("TestTimeoutHandler", android.os.Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.start(); Looper timeoutLooper = mHandlerThread.getLooper(); mMessageHandler = new Handler(timeoutLooper, this); // Initiate self destruction. mMessageHandler.sendEmptyMessageDelayed(MSG_ID_TIMEOUT, TIMEOUT_VALUE); } // OBEX operation handlers @Override public int onConnect(HeaderSet request, HeaderSet reply) { if(V) Log.i(TAG,"onConnect() returning error"); return mResult; } public void shutdown() { mMessageHandler.removeCallbacksAndMessages(null); mHandlerThread.quit(); try { // This will cause an exception in the ServerSession, causing it to shut down mSocket.close(); } catch (IOException e) { Log.w(TAG, "Unable to close socket - ignoring", e); } } @Override public boolean handleMessage(Message msg) { if(V) Log.i(TAG,"Handling message ID: " + msg.what); switch(msg.what) { case MSG_ID_TIMEOUT: shutdown(); break; default: // Message not handled return false; } return true; // Message handled } }