| /* |
| * 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 |
| } |
| } |