platform/bb/rhodes/src/com/rho/RhodesApplicationPlatform.java in rhodes-2.2.6 vs platform/bb/rhodes/src/com/rho/RhodesApplicationPlatform.java in rhodes-2.3.0.beta.1

- old
+ new

@@ -1,14 +1,254 @@ package com.rho; -import net.rim.device.api.ui.UiApplication; +import java.io.InputStream; -public class RhodesApplicationPlatform extends UiApplication +import javax.microedition.io.StreamConnection; + +import com.rho.RhoClassFactory; +import com.rho.RhoEmptyLogger; +import com.rho.RhoLogger; +import com.rho.RhoThread; +import com.rho.RhodesApp; +import com.rho.ThreadQueue; +import com.rho.ThreadQueue.IQueueCommand; +import com.rho.net.URI; + +import net.rim.blackberry.api.push.*; +import net.rim.device.api.io.http.PushInputStream; +import net.rim.device.api.system.ApplicationDescriptor; +import net.rim.device.api.ui.UiApplication; +import net.rim.device.api.util.DataBuffer; +/** + * + */ +public class RhodesApplicationPlatform extends UiApplication implements PushApplication { + private static final RhoLogger LOG = RhoLogger.RHO_STRIP_LOG ? new RhoEmptyLogger() : + new RhoLogger("RhodesPUSH"); + + private static final int CHUNK_SIZE = 256; + PushMessageThread m_PushMessageThread; + + private static class PushStatusCommand implements IQueueCommand + { + String m_strStatus; + + public PushStatusCommand(String strStatus) + { + m_strStatus = strStatus; + } + public boolean equals(IQueueCommand cmd){return false;} + + public void execute() + { + try + { + RhodesApp.getInstance().callPushCallback(m_strStatus); + }catch(Exception exc) + { + LOG.ERROR("callPushCallback failed.", exc); + } + } + } + + private static class PushMessageCommand implements IQueueCommand + { + PushInputStream m_inputStream; + StreamConnection m_conn; + + public PushMessageCommand(PushInputStream inputStream, StreamConnection conn) + { + m_inputStream = inputStream; + m_conn = conn; + } + public boolean equals(IQueueCommand cmd){return false;} + + public void execute() + { + InputStream input = null; + + try + { + input = m_conn.openInputStream(); + DataBuffer db = new DataBuffer(); + byte[] data = new byte[CHUNK_SIZE]; + int chunk = 0; + + while ( -1 != (chunk = input.read(data)) ) + { + db.write(data, 0, chunk); + } + + data = db.getArray(); + + try + { + rhomobile.PushListeningThread.processPushMessage(data, db.getLength()); + }catch(Exception exc) + { + LOG.ERROR("processPushMessage failed.Data: " + new String(data), exc); + }catch(Throwable th) + { + LOG.ERROR("processPushMessage crashed.Data: " + new String(data), th); + } + }catch(Exception exc) + { + LOG.ERROR("Read PUSH message failed.", exc); + }catch(Throwable th) + { + LOG.ERROR("Read PUSH message crashed.", th); + }finally + { + try + { + m_inputStream.accept(); + + if ( input != null) + input.close(); + + m_inputStream.close(); + m_conn.close(); + }catch(Exception exc) + { + + } + } + } + + } + + private static class PushMessageThread extends ThreadQueue + { + public PushMessageThread() + { + super(new RhoClassFactory()); + + ThreadQueue.setLogCategory(LOG.getLogCategory()); + + setPollInterval(QUEUE_POLL_INTERVAL_INFINITE); + + start(epLow); + } + + public void processCommand(IQueueCommand pCmd) + { + ((PushMessageCommand)pCmd).execute(); + } + } + + public void onMessage(PushInputStream inputStream, StreamConnection conn) + { + LOG.INFO("onMessage"); + m_PushMessageThread.addQueueCommand( new PushMessageCommand(inputStream, conn) ); + } + + public void onStatusChange(PushApplicationStatus status) + { + String strError = status.getError(); + + String strStatus = "", strRegReason = ""; + + switch( status.getStatus() ) + { + case PushApplicationStatus.STATUS_ACTIVE: + strStatus = "Active"; + break; + case PushApplicationStatus.STATUS_FAILED: + strStatus = "Failed"; + break; + case PushApplicationStatus.STATUS_NOT_REGISTERED: + strStatus = "Not Registered"; + break; + case PushApplicationStatus.STATUS_PENDING: + strStatus = "Pending"; + break; + } + + switch( status.getReason() ) { + case PushApplicationStatus.REASON_SIM_CHANGE: + strRegReason = "Status change was initiated by SIM card change"; + break; + case PushApplicationStatus.REASON_API_CALL: + strRegReason = "Status change was initiated by API call"; + break; + case PushApplicationStatus.REASON_REJECTED_BY_SERVER: + strRegReason = "Registration was rejected by server "; + break; + case PushApplicationStatus.REASON_NETWORK_ERROR: + strRegReason = "Communication failed due to network error "; + break; + case PushApplicationStatus.REASON_INVALID_PARAMETERS: + strRegReason = "Invalid parameters were provided that caused registration failure "; + break; + } + + String strMsg = "status="+URI.urlEncode(strStatus)+"&reason="+URI.urlEncode(strRegReason); + + if ( strError != null && strError.length() > 0 ) + strMsg += "&error="+URI.urlEncode(strError); + + LOG.INFO("onStatusChange : " + strMsg); + + if ( m_PushMessageThread != null ) + m_PushMessageThread.addQueueCommand( new PushStatusCommand(strMsg) ); + } + public void onPlatformActivate() { + if ( com.rho.Capabilities.ENABLE_PUSH ) + { + if ( !rhomobile.PushListeningThread.isPushServiceEnabled() ) + return; + + getUiApplication().invokeLater( new Runnable() + { + public void run() + { + try + { + m_PushMessageThread = new PushMessageThread(); + String strAppName = RhoConf.getInstance().getString("push_service_appname"); + String strUrl = RhoConf.getInstance().getString("push_service_url"); + if ( strAppName != null && strAppName.length() > 0 && strUrl != null && strUrl.length() > 0 ) + { + int nPort = RhoConf.getInstance().getInt("push_service_port"); + byte btServiceType = RhoConf.getInstance().getString("push_service_type").equalsIgnoreCase("BPAS") ? + PushApplicationDescriptor.SERVER_TYPE_BPAS : PushApplicationDescriptor.SERVER_TYPE_NONE; + + PushApplicationDescriptor pad = new PushApplicationDescriptor( + strAppName, nPort, strUrl, btServiceType, + ApplicationDescriptor.currentApplicationDescriptor()); + + PushApplicationStatus status = PushApplicationRegistry.getStatus(pad); + + LOG.INFO("registerPushService status : " + status.toString()); + + if (status.getStatus() != PushApplicationStatus.STATUS_ACTIVE && status.getStatus() != PushApplicationStatus.STATUS_PENDING) + { + + LOG.INFO("registerPushService registering push"); + + PushApplicationRegistry.registerApplication(pad); + } + } + }catch(Exception exc) + { + LOG.ERROR("registerPushService failed.", exc); + }catch(Throwable t) + { + LOG.ERROR("registerPushService crashed.", t); + } + } + }); + } } public void onPlatformClose() { + if ( m_PushMessageThread != null ) + m_PushMessageThread.stop(3); + + m_PushMessageThread = null; } + }