/** * Posts the specified command to be executed on the main thread, waits for the request to * complete, and returns the result. * * @see sendRequestAsync */ private Object sendRequest(int command, Object argument) { if (Looper.myLooper() == mMainThreadHandler.getLooper()) { throw new RuntimeException("This method will deadlock if called from the main thread."); } MainThreadRequest request = new MainThreadRequest(argument); Message msg = mMainThreadHandler.obtainMessage(command, request); msg.sendToTarget(); // Wait for the request to complete synchronized (request) { while (request.result == null) { try { request.wait(); } catch (InterruptedException e) { // Do nothing, go back and wait until the request is complete } } } return request.result; }
@Override public void handleMessage(Message msg) { MainThreadRequest request; Message onCompleted; AsyncResult ar; switch (msg.what) { case CMD_HANDLE_PIN_MMI: request = (MainThreadRequest) msg.obj; request.result = Boolean.valueOf(mPhone.handlePinMmi((String) request.argument)); // Wake up the requesting thread synchronized (request) { request.notifyAll(); } break; case CMD_HANDLE_NEIGHBORING_CELL: request = (MainThreadRequest) msg.obj; onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, request); mPhone.getNeighboringCids(onCompleted); break; case EVENT_NEIGHBORING_CELL_DONE: ar = (AsyncResult) msg.obj; request = (MainThreadRequest) ar.userObj; if (ar.exception == null && ar.result != null) { request.result = ar.result; } else { // create an empty list to notify the waiting thread request.result = new ArrayList<NeighboringCellInfo>(); } // Wake up the requesting thread synchronized (request) { request.notifyAll(); } break; case CMD_ANSWER_RINGING_CALL: answerRingingCallInternal(); break; case CMD_SILENCE_RINGER: silenceRingerInternal(); break; case CMD_END_CALL: request = (MainThreadRequest) msg.obj; boolean hungUp = false; int phoneType = mPhone.getPhoneType(); if (phoneType == Phone.PHONE_TYPE_CDMA) { // CDMA: If the user presses the Power button we treat it as // ending the complete call session hungUp = PhoneUtils.hangupRingingAndActive(mPhone); } else if (phoneType == Phone.PHONE_TYPE_GSM) { // GSM: End all calls except waiting hungUp = PhoneUtils.hangupAllCalls(mPhone); } else { throw new IllegalStateException("Unexpected phone type: " + phoneType); } if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); request.result = hungUp; // Wake up the requesting thread synchronized (request) { request.notifyAll(); } break; case CMD_INVOKE_OEM_RIL_REQUEST: request = (MainThreadRequest) msg.obj; onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST, request); mPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted); break; case EVENT_INVOKE_OEM_RIL_REQUEST: ar = (AsyncResult) msg.obj; request = (MainThreadRequest) ar.userObj; request.result = ar; // Wake up the requesting thread synchronized (request) { request.notifyAll(); } break; case EVENT_UNSOL_OEM_HOOK_EXT_APP: ar = (AsyncResult) msg.obj; broadcastUnsolOemHookIntent((byte[]) (ar.result)); break; case CMD_SET_TRANSMIT_POWER: request = (MainThreadRequest) msg.obj; onCompleted = obtainMessage(EVENT_SET_TRANSMIT_POWER_DONE, request); mPhone.setTransmitPower((Integer) request.argument, onCompleted); break; case EVENT_SET_TRANSMIT_POWER_DONE: boolean retStatus = false; ar = (AsyncResult) msg.obj; request = (MainThreadRequest) ar.userObj; if (ar.exception == null) { retStatus = true; } request.result = retStatus; // Wake up the requesting thread synchronized (request) { request.notifyAll(); } break; default: Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); break; } }