1 /* 2 * Copyright (C) 2015 Samsung System LSI 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 package com.android.bluetooth; 16 17 import java.io.IOException; 18 19 import javax.obex.HeaderSet; 20 import javax.obex.ServerRequestHandler; 21 22 import android.bluetooth.BluetoothSocket; 23 import android.os.Handler; 24 import android.os.Handler.Callback; 25 import android.os.HandlerThread; 26 import android.os.Looper; 27 import android.os.Message; 28 import android.util.Log; 29 30 /** 31 * A simple ObexServer used to handle connection rejection in two cases: 32 * - A profile cannot handle a new connection, as it is already connected to another device. 33 * - The user rejected access to the resources needed by the profile. 34 * 35 * Will reject the OBEX connection, start a timer, and at timeout close the socket. 36 */ 37 public class ObexRejectServer extends ServerRequestHandler implements Callback { 38 39 private static final String TAG = "ObexRejectServer"; 40 private static final boolean V = true; 41 private final int mResult; 42 private final HandlerThread mHandlerThread; 43 private final Handler mMessageHandler; 44 private final static int MSG_ID_TIMEOUT = 0x01; 45 private final static int TIMEOUT_VALUE = 5*1000; // ms 46 private final BluetoothSocket mSocket; 47 48 /** 49 * @param result the ResponseCodes.OBEX_HTTP_ code to respond to an incoming connect request. 50 */ ObexRejectServer(int result, BluetoothSocket socket)51 public ObexRejectServer(int result, BluetoothSocket socket) { 52 super(); 53 mResult = result; 54 mSocket = socket; 55 mHandlerThread = new HandlerThread("TestTimeoutHandler", 56 android.os.Process.THREAD_PRIORITY_BACKGROUND); 57 mHandlerThread.start(); 58 Looper timeoutLooper = mHandlerThread.getLooper(); 59 mMessageHandler = new Handler(timeoutLooper, this); 60 // Initiate self destruction. 61 mMessageHandler.sendEmptyMessageDelayed(MSG_ID_TIMEOUT, TIMEOUT_VALUE); 62 } 63 64 // OBEX operation handlers 65 @Override onConnect(HeaderSet request, HeaderSet reply)66 public int onConnect(HeaderSet request, HeaderSet reply) { 67 if(V) Log.i(TAG,"onConnect() returning error"); 68 return mResult; 69 } 70 shutdown()71 public void shutdown() { 72 mMessageHandler.removeCallbacksAndMessages(null); 73 mHandlerThread.quit(); 74 try { 75 // This will cause an exception in the ServerSession, causing it to shut down 76 mSocket.close(); 77 } catch (IOException e) { 78 Log.w(TAG, "Unable to close socket - ignoring", e); 79 } 80 } 81 82 @Override handleMessage(Message msg)83 public boolean handleMessage(Message msg) { 84 if(V) Log.i(TAG,"Handling message ID: " + msg.what); 85 switch(msg.what) { 86 case MSG_ID_TIMEOUT: 87 shutdown(); 88 break; 89 default: 90 // Message not handled 91 return false; 92 } 93 return true; // Message handled 94 } 95 } 96