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 android.bluetooth.BluetoothSocket; 19 import android.os.Handler; 20 import android.os.Handler.Callback; 21 import android.os.HandlerThread; 22 import android.os.Looper; 23 import android.os.Message; 24 import android.util.Log; 25 26 import java.io.IOException; 27 28 import javax.obex.HeaderSet; 29 import javax.obex.ServerRequestHandler; 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 static final int MSG_ID_TIMEOUT = 0x01; 46 private static final 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) { 69 Log.i(TAG, "onConnect() returning error"); 70 } 71 return mResult; 72 } 73 shutdown()74 public void shutdown() { 75 mMessageHandler.removeCallbacksAndMessages(null); 76 mHandlerThread.quit(); 77 try { 78 // This will cause an exception in the ServerSession, causing it to shut down 79 mSocket.close(); 80 } catch (IOException e) { 81 Log.w(TAG, "Unable to close socket - ignoring", e); 82 } 83 } 84 85 @Override handleMessage(Message msg)86 public boolean handleMessage(Message msg) { 87 if (V) { 88 Log.i(TAG, "Handling message ID: " + msg.what); 89 } 90 switch (msg.what) { 91 case MSG_ID_TIMEOUT: 92 shutdown(); 93 break; 94 default: 95 // Message not handled 96 return false; 97 } 98 return true; // Message handled 99 } 100 } 101