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 16 package com.android.bluetooth; 17 18 import java.io.IOException; 19 20 import javax.obex.HeaderSet; 21 import javax.obex.ServerRequestHandler; 22 23 import android.bluetooth.BluetoothSocket; 24 import android.os.Handler; 25 import android.os.Handler.Callback; 26 import android.os.HandlerThread; 27 import android.os.Looper; 28 import android.os.Message; 29 import android.util.Log; 30 31 /** 32 * A simple ObexServer used to handle connection rejection in two cases: 33 * - A profile cannot handle a new connection, as it is already connected to another device. 34 * - The user rejected access to the resources needed by the profile. 35 * 36 * Will reject the OBEX connection, start a timer, and at timeout close the socket. 37 */ 38 public class ObexRejectServer extends ServerRequestHandler implements Callback { 39 40 private static final String TAG = "ObexRejectServer"; 41 private static final boolean V = true; 42 private final int mResult; 43 private final HandlerThread mHandlerThread; 44 private final Handler mMessageHandler; 45 private final static int MSG_ID_TIMEOUT = 0x01; 46 private final static int TIMEOUT_VALUE = 5*1000; // ms 47 private final BluetoothSocket mSocket; 48 49 /** 50 * @param result the ResponseCodes.OBEX_HTTP_ code to respond to an incoming connect request. 51 */ ObexRejectServer(int result, BluetoothSocket socket)52 public ObexRejectServer(int result, BluetoothSocket socket) { 53 super(); 54 mResult = result; 55 mSocket = socket; 56 mHandlerThread = new HandlerThread("TestTimeoutHandler", 57 android.os.Process.THREAD_PRIORITY_BACKGROUND); 58 mHandlerThread.start(); 59 Looper timeoutLooper = mHandlerThread.getLooper(); 60 mMessageHandler = new Handler(timeoutLooper, this); 61 // Initiate self destruction. 62 mMessageHandler.sendEmptyMessageDelayed(MSG_ID_TIMEOUT, TIMEOUT_VALUE); 63 } 64 65 // OBEX operation handlers 66 @Override onConnect(HeaderSet request, HeaderSet reply)67 public int onConnect(HeaderSet request, HeaderSet reply) { 68 if(V) Log.i(TAG,"onConnect() returning error"); 69 return mResult; 70 } 71 shutdown()72 public void shutdown() { 73 mMessageHandler.removeCallbacksAndMessages(null); 74 mHandlerThread.quit(); 75 try { 76 // This will cause an exception in the ServerSession, causing it to shut down 77 mSocket.close(); 78 } catch (IOException e) { 79 Log.w(TAG, "Unable to close socket - ignoring", e); 80 } 81 } 82 83 @Override handleMessage(Message msg)84 public boolean handleMessage(Message msg) { 85 if(V) Log.i(TAG,"Handling message ID: " + msg.what); 86 switch(msg.what) { 87 case MSG_ID_TIMEOUT: 88 shutdown(); 89 break; 90 default: 91 // Message not handled 92 return false; 93 } 94 return true; // Message handled 95 } 96 } 97