Changeset 5017


Ignore:
Timestamp:
Mar 22, 2015 10:22:44 AM (6 years ago)
Author:
nanang
Message:

Misc (re #1782): Coding style works (indentation, etc) on Android pjsua2 sample app codes.

Location:
pjproject/trunk/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java

    r5014 r5017  
    3232 
    3333public class CallActivity extends Activity 
    34         implements Handler.Callback, SurfaceHolder.Callback 
     34                          implements Handler.Callback, SurfaceHolder.Callback 
    3535{ 
    36          
    37         public static Handler handler_; 
    38  
    39         private final Handler handler = new Handler(this); 
    40         private static CallInfo lastCallInfo; 
    41  
    42         @Override 
    43         protected void onCreate(Bundle savedInstanceState) { 
    44                 super.onCreate(savedInstanceState); 
    45                 setContentView(R.layout.activity_call); 
    46                  
    47                 SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceIncomingVideo); 
    48                 if (MainActivity.currentCall == null || 
    49                         MainActivity.currentCall.vidWin == null) 
    50                 { 
    51                         surfaceView.setVisibility(View.GONE); 
    52                 } 
    53                 surfaceView.getHolder().addCallback(this); 
    54                  
    55                 handler_ = handler; 
    56                 if (MainActivity.currentCall != null) { 
    57                         try { 
    58                                 lastCallInfo = MainActivity.currentCall.getInfo(); 
    59                                 updateCallState(lastCallInfo); 
    60                         } catch (Exception e) { 
    61                                 System.out.println(e); 
    62                         } 
    63                 } else { 
    64                         updateCallState(lastCallInfo); 
    65                 } 
    66         } 
     36 
     37    public static Handler handler_; 
     38 
     39    private final Handler handler = new Handler(this); 
     40    private static CallInfo lastCallInfo; 
    6741 
    6842    @Override 
    69     protected void onDestroy() { 
    70         super.onDestroy(); 
    71         handler_ = null; 
    72     } 
    73  
    74     private void updateVideoWindow(SurfaceHolder holder) { 
    75                 if (MainActivity.currentCall != null && 
    76                         MainActivity.currentCall.vidWin != null) 
    77                 { 
    78                         VideoWindowHandle vidWH = new VideoWindowHandle(); 
    79                         if (holder == null) 
    80                                 vidWH.getHandle().setWindow(null); 
    81                         else 
    82                                 vidWH.getHandle().setWindow(holder.getSurface()); 
    83                         try { 
    84                                 MainActivity.currentCall.vidWin.setWindow(vidWH); 
    85                         } catch (Exception e) {} 
    86                 } 
    87     } 
    88      
    89         public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    90                 updateVideoWindow(holder); 
    91     } 
    92  
    93     public void surfaceCreated(SurfaceHolder holder) { 
    94     } 
    95  
    96     public void surfaceDestroyed(SurfaceHolder holder) { 
    97         updateVideoWindow(null); 
    98     } 
    99      
    100         public void acceptCall(View view) { 
    101                 CallOpParam prm = new CallOpParam(); 
    102                 prm.setStatusCode(pjsip_status_code.PJSIP_SC_OK); 
    103                 try { 
    104                         MainActivity.currentCall.answer(prm); 
    105                 } catch (Exception e) { 
    106                         System.out.println(e); 
    107                 } 
    108                  
    109                 view.setVisibility(View.GONE); 
    110         } 
    111  
    112         public void hangupCall(View view) { 
    113                 handler_ = null; 
    114                 finish(); 
    115                  
    116                 if (MainActivity.currentCall != null) { 
    117                         CallOpParam prm = new CallOpParam(); 
    118                         prm.setStatusCode(pjsip_status_code.PJSIP_SC_DECLINE); 
    119                         try { 
    120                                 MainActivity.currentCall.hangup(prm); 
    121                         } catch (Exception e) { 
    122                                 System.out.println(e); 
    123                         } 
    124                 } 
    125         } 
    126          
    127         private void setupVideoSurface() { 
    128  
    129                 SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceIncomingVideo); 
    130                 surfaceView.setVisibility(View.VISIBLE); 
    131                 updateVideoWindow(surfaceView.getHolder()); 
    132                  
    133         } 
    134          
    135         @Override 
    136         public boolean handleMessage(Message m) { 
    137                  
    138                 if (m.what == MainActivity.MSG_TYPE.CALL_STATE) { 
    139                          
    140                         lastCallInfo = (CallInfo) m.obj; 
    141                         updateCallState(lastCallInfo); 
    142                          
    143                 } else if (m.what == MainActivity.MSG_TYPE.CALL_MEDIA_STATE) { 
    144                          
    145                         if (MainActivity.currentCall.vidWin != null) { 
    146                                 /* If there's incoming video, display it. */ 
    147                                 setupVideoSurface(); 
    148                         } 
    149  
    150                 } else { 
    151                          
    152                         /* Message not handled */ 
    153                         return false; 
    154                          
    155                 } 
    156                          
    157                 return true; 
    158         } 
    159          
    160         private void updateCallState(CallInfo ci) { 
    161                 TextView tvPeer  = (TextView) findViewById(R.id.textViewPeer); 
    162                 TextView tvState = (TextView) findViewById(R.id.textViewCallState); 
    163                 Button buttonHangup = (Button) findViewById(R.id.buttonHangup); 
    164                 Button buttonAccept = (Button) findViewById(R.id.buttonAccept); 
    165                 String call_state = ""; 
    166                  
    167                 if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAC) { 
    168                         buttonAccept.setVisibility(View.GONE); 
    169                 } 
    170                                  
    171                 if (ci.getState().swigValue() < pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()) 
    172                 { 
    173                         if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAS) { 
    174                                 call_state = "Incoming call.."; 
    175                                 /* Default button texts are already 'Accept' & 'Reject' */ 
    176                         } else { 
    177                                 buttonHangup.setText("Cancel"); 
    178                                 call_state = ci.getStateText(); 
    179                         } 
    180                 } 
    181                 else if (ci.getState().swigValue() >= pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()) 
    182                 { 
    183                         buttonAccept.setVisibility(View.GONE); 
    184                         call_state = ci.getStateText(); 
    185                         if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) { 
    186                                 buttonHangup.setText("Hangup"); 
    187                         } else if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) { 
    188                                 buttonHangup.setText("OK"); 
    189                                 call_state = "Call disconnected: " + ci.getLastReason(); 
    190                         } 
    191                 } 
    192                  
    193                 tvPeer.setText(ci.getRemoteUri()); 
    194                 tvState.setText(call_state); 
    195         } 
     43    protected void onCreate(Bundle savedInstanceState) 
     44    { 
     45        super.onCreate(savedInstanceState); 
     46        setContentView(R.layout.activity_call); 
     47 
     48        SurfaceView surfaceView = (SurfaceView) 
     49                                  findViewById(R.id.surfaceIncomingVideo); 
     50        if (MainActivity.currentCall == null || 
     51            MainActivity.currentCall.vidWin == null) 
     52        { 
     53            surfaceView.setVisibility(View.GONE); 
     54        } 
     55        surfaceView.getHolder().addCallback(this); 
     56 
     57        handler_ = handler; 
     58        if (MainActivity.currentCall != null) { 
     59            try { 
     60                lastCallInfo = MainActivity.currentCall.getInfo(); 
     61                updateCallState(lastCallInfo); 
     62            } catch (Exception e) { 
     63                System.out.println(e); 
     64            } 
     65        } else { 
     66            updateCallState(lastCallInfo); 
     67        } 
     68    } 
     69 
     70    @Override 
     71    protected void onDestroy() 
     72    { 
     73        super.onDestroy(); 
     74        handler_ = null; 
     75    } 
     76 
     77    private void updateVideoWindow(SurfaceHolder holder) 
     78    { 
     79        if (MainActivity.currentCall != null && 
     80            MainActivity.currentCall.vidWin != null) 
     81        { 
     82            VideoWindowHandle vidWH = new VideoWindowHandle(); 
     83            if (holder == null) 
     84                vidWH.getHandle().setWindow(null); 
     85            else 
     86                vidWH.getHandle().setWindow(holder.getSurface()); 
     87            try { 
     88                MainActivity.currentCall.vidWin.setWindow(vidWH); 
     89            } catch (Exception e) {} 
     90        } 
     91    } 
     92 
     93    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
     94    { 
     95        updateVideoWindow(holder); 
     96    } 
     97 
     98    public void surfaceCreated(SurfaceHolder holder) 
     99    { 
     100    } 
     101 
     102    public void surfaceDestroyed(SurfaceHolder holder) 
     103    { 
     104        updateVideoWindow(null); 
     105    } 
     106 
     107    public void acceptCall(View view) 
     108    { 
     109        CallOpParam prm = new CallOpParam(); 
     110        prm.setStatusCode(pjsip_status_code.PJSIP_SC_OK); 
     111        try { 
     112            MainActivity.currentCall.answer(prm); 
     113        } catch (Exception e) { 
     114            System.out.println(e); 
     115        } 
     116 
     117        view.setVisibility(View.GONE); 
     118    } 
     119 
     120    public void hangupCall(View view) 
     121    { 
     122        handler_ = null; 
     123        finish(); 
     124 
     125        if (MainActivity.currentCall != null) { 
     126            CallOpParam prm = new CallOpParam(); 
     127            prm.setStatusCode(pjsip_status_code.PJSIP_SC_DECLINE); 
     128            try { 
     129                MainActivity.currentCall.hangup(prm); 
     130            } catch (Exception e) { 
     131                System.out.println(e); 
     132            } 
     133        } 
     134    } 
     135 
     136    private void setupVideoSurface() 
     137    { 
     138        SurfaceView surfaceView = (SurfaceView) 
     139                                  findViewById(R.id.surfaceIncomingVideo); 
     140        surfaceView.setVisibility(View.VISIBLE); 
     141        updateVideoWindow(surfaceView.getHolder()); 
     142    } 
     143 
     144    @Override 
     145    public boolean handleMessage(Message m) 
     146    { 
     147        if (m.what == MainActivity.MSG_TYPE.CALL_STATE) { 
     148 
     149            lastCallInfo = (CallInfo) m.obj; 
     150            updateCallState(lastCallInfo); 
     151 
     152        } else if (m.what == MainActivity.MSG_TYPE.CALL_MEDIA_STATE) { 
     153 
     154            if (MainActivity.currentCall.vidWin != null) { 
     155                /* If there's incoming video, display it. */ 
     156                setupVideoSurface(); 
     157            } 
     158 
     159        } else { 
     160 
     161            /* Message not handled */ 
     162            return false; 
     163 
     164        } 
     165 
     166        return true; 
     167    } 
     168 
     169    private void updateCallState(CallInfo ci) { 
     170        TextView tvPeer  = (TextView) findViewById(R.id.textViewPeer); 
     171        TextView tvState = (TextView) findViewById(R.id.textViewCallState); 
     172        Button buttonHangup = (Button) findViewById(R.id.buttonHangup); 
     173        Button buttonAccept = (Button) findViewById(R.id.buttonAccept); 
     174        String call_state = ""; 
     175 
     176        if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAC) { 
     177            buttonAccept.setVisibility(View.GONE); 
     178        } 
     179 
     180        if (ci.getState().swigValue() < 
     181            pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()) 
     182        { 
     183            if (ci.getRole() == pjsip_role_e.PJSIP_ROLE_UAS) { 
     184                call_state = "Incoming call.."; 
     185                /* Default button texts are already 'Accept' & 'Reject' */ 
     186            } else { 
     187                buttonHangup.setText("Cancel"); 
     188                call_state = ci.getStateText(); 
     189            } 
     190        } 
     191        else if (ci.getState().swigValue() >= 
     192                 pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED.swigValue()) 
     193        { 
     194            buttonAccept.setVisibility(View.GONE); 
     195            call_state = ci.getStateText(); 
     196            if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_CONFIRMED) { 
     197                buttonHangup.setText("Hangup"); 
     198            } else if (ci.getState() == 
     199                       pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) 
     200            { 
     201                buttonHangup.setText("OK"); 
     202                call_state = "Call disconnected: " + ci.getLastReason(); 
     203            } 
     204        } 
     205 
     206        tvPeer.setText(ci.getRemoteUri()); 
     207        tvState.setText(call_state); 
     208    } 
    196209} 
  • pjproject/trunk/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java

    r4997 r5017  
    4444import org.pjsip.pjsua2.*; 
    4545 
    46 public class MainActivity extends Activity implements Handler.Callback, MyAppObserver { 
    47         public static MyApp app = null; 
    48         public static MyCall currentCall = null; 
    49         public static MyAccount account = null; 
    50         public static AccountConfig accCfg = null; 
    51          
    52         private ListView buddyListView; 
    53         private SimpleAdapter buddyListAdapter; 
    54         private int buddyListSelectedIdx = -1; 
     46public class MainActivity extends Activity 
     47                          implements Handler.Callback, MyAppObserver 
     48{ 
     49    public static MyApp app = null; 
     50    public static MyCall currentCall = null; 
     51    public static MyAccount account = null; 
     52    public static AccountConfig accCfg = null; 
     53 
     54    private ListView buddyListView; 
     55    private SimpleAdapter buddyListAdapter; 
     56    private int buddyListSelectedIdx = -1; 
    5557    ArrayList<Map<String, String>> buddyList; 
    5658    private String lastRegStatus = ""; 
    5759 
    58         private final Handler handler = new Handler(this); 
    59         public class MSG_TYPE { 
    60                 public final static int INCOMING_CALL = 1; 
    61                 public final static int CALL_STATE = 2; 
    62                 public final static int REG_STATE = 3; 
    63                 public final static int BUDDY_STATE = 4; 
    64                 public final static int CALL_MEDIA_STATE = 5; 
    65         } 
    66  
    67         private HashMap<String, String> putData(String uri, String status) { 
    68                 HashMap<String, String> item = new HashMap<String, String>(); 
    69                 item.put("uri", uri); 
    70                 item.put("status", status); 
    71                 return item; 
    72         } 
    73          
    74         private void showCallActivity() { 
    75         Intent intent = new Intent(this, CallActivity.class); 
    76         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    77         startActivity(intent); 
    78         } 
    79  
    80         @Override 
    81         protected void onCreate(Bundle savedInstanceState) { 
    82                 super.onCreate(savedInstanceState); 
    83                 setContentView(R.layout.activity_main); 
    84                  
    85                 if (app == null) { 
    86                         app = new MyApp(); 
    87                         /* Wait for GDB to init */ 
    88                         if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 
    89                                 try { 
    90                                         Thread.sleep(5000); 
    91                                 } catch (InterruptedException e) {} 
     60    private final Handler handler = new Handler(this); 
     61    public class MSG_TYPE 
     62    { 
     63        public final static int INCOMING_CALL = 1; 
     64        public final static int CALL_STATE = 2; 
     65        public final static int REG_STATE = 3; 
     66        public final static int BUDDY_STATE = 4; 
     67        public final static int CALL_MEDIA_STATE = 5; 
     68    } 
     69 
     70    private HashMap<String, String> putData(String uri, String status) 
     71    { 
     72        HashMap<String, String> item = new HashMap<String, String>(); 
     73        item.put("uri", uri); 
     74        item.put("status", status); 
     75        return item; 
     76    } 
     77 
     78    private void showCallActivity() 
     79    { 
     80        Intent intent = new Intent(this, CallActivity.class); 
     81        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     82        startActivity(intent); 
     83    } 
     84 
     85    @Override 
     86    protected void onCreate(Bundle savedInstanceState) 
     87    { 
     88        super.onCreate(savedInstanceState); 
     89        setContentView(R.layout.activity_main); 
     90 
     91        if (app == null) { 
     92            app = new MyApp(); 
     93            // Wait for GDB to init, for native debugging only 
     94            if (false && 
     95                (getApplicationInfo().flags &  
     96                ApplicationInfo.FLAG_DEBUGGABLE) != 0) 
     97            { 
     98                try { 
     99                    Thread.sleep(5000); 
     100                } catch (InterruptedException e) {} 
     101            } 
     102 
     103            app.init(this, getFilesDir().getAbsolutePath()); 
     104        } 
     105 
     106        if (app.accList.size() == 0) { 
     107            accCfg = new AccountConfig(); 
     108            accCfg.setIdUri("sip:localhost"); 
     109            accCfg.getNatConfig().setIceEnabled(true); 
     110            account = app.addAcc(accCfg); 
     111        } else { 
     112            account = app.accList.get(0); 
     113            accCfg = account.cfg; 
     114        } 
     115 
     116        buddyList = new ArrayList<Map<String, String>>(); 
     117        for (int i = 0; i < account.buddyList.size(); i++) { 
     118            buddyList.add(putData(account.buddyList.get(i).cfg.getUri(), 
     119                                  account.buddyList.get(i).getStatusText())); 
     120        } 
     121 
     122        String[] from = { "uri", "status" }; 
     123        int[] to = { android.R.id.text1, android.R.id.text2 }; 
     124        buddyListAdapter = new SimpleAdapter( 
     125                                        this, buddyList, 
     126                                        android.R.layout.simple_list_item_2, 
     127                                        from, to); 
     128 
     129        buddyListView = (ListView) findViewById(R.id.listViewBuddy);; 
     130        buddyListView.setAdapter(buddyListAdapter); 
     131        buddyListView.setOnItemClickListener( 
     132            new AdapterView.OnItemClickListener() 
     133            { 
     134                @Override 
     135                public void onItemClick(AdapterView<?> parent, 
     136                                        final View view, 
     137                                        int position, long id)  
     138                { 
     139                    view.setSelected(true); 
     140                    buddyListSelectedIdx = position; 
     141                } 
     142            } 
     143        ); 
     144 
     145    } 
     146 
     147    @Override 
     148    public boolean onCreateOptionsMenu(Menu menu) 
     149    { 
     150        // Inflate the menu; this adds items to the action bar 
     151        // if it is present. 
     152        getMenuInflater().inflate(R.menu.main, menu); 
     153        return true; 
     154    } 
     155 
     156    @Override 
     157    public boolean onOptionsItemSelected(MenuItem item) 
     158    { 
     159        switch (item.getItemId()) { 
     160            case R.id.action_acc_config: 
     161                dlgAccountSetting(); 
     162                break; 
     163 
     164            case R.id.action_quit: 
     165                Message m = Message.obtain(handler, 0); 
     166                m.sendToTarget(); 
     167                break; 
     168 
     169            default: 
     170                break; 
     171        } 
     172 
     173        return true; 
     174    }    
     175 
     176    @Override 
     177    public boolean handleMessage(Message m) 
     178    { 
     179        if (m.what == 0) { 
     180 
     181            app.deinit(); 
     182            finish(); 
     183            Runtime.getRuntime().gc(); 
     184            android.os.Process.killProcess(android.os.Process.myPid()); 
     185 
     186        } else if (m.what == MSG_TYPE.CALL_STATE) { 
     187 
     188            CallInfo ci = (CallInfo) m.obj; 
     189 
     190            /* Forward the message to CallActivity */ 
     191            if (CallActivity.handler_ != null) { 
     192                Message m2 = Message.obtain(CallActivity.handler_, 
     193                    MSG_TYPE.CALL_STATE, ci); 
     194                m2.sendToTarget(); 
     195            } 
     196 
     197        } else if (m.what == MSG_TYPE.CALL_MEDIA_STATE) { 
     198 
     199            /* Forward the message to CallActivity */ 
     200            if (CallActivity.handler_ != null) { 
     201                Message m2 = Message.obtain(CallActivity.handler_, 
     202                    MSG_TYPE.CALL_MEDIA_STATE, 
     203                    null); 
     204                m2.sendToTarget(); 
     205            } 
     206 
     207        } else if (m.what == MSG_TYPE.BUDDY_STATE) { 
     208 
     209            MyBuddy buddy = (MyBuddy) m.obj; 
     210            int idx = account.buddyList.indexOf(buddy); 
     211 
     212            /* Update buddy status text, if buddy is valid and 
     213            * the buddy lists in account and UI are sync-ed. 
     214            */ 
     215            if (idx >= 0 && account.buddyList.size() == buddyList.size()) 
     216            { 
     217                buddyList.get(idx).put("status", buddy.getStatusText()); 
     218                buddyListAdapter.notifyDataSetChanged(); 
     219                // TODO: selection color/mark is gone after this, 
     220                //       dont know how to return it back. 
     221                //buddyListView.setSelection(buddyListSelectedIdx); 
     222                //buddyListView.performItemClick(buddyListView, 
     223                //                                   buddyListSelectedIdx, 
     224                //                                   buddyListView. 
     225                //                  getItemIdAtPosition(buddyListSelectedIdx)); 
     226 
     227                /* Return back Call activity */ 
     228                notifyCallState(currentCall); 
     229            } 
     230 
     231        } else if (m.what == MSG_TYPE.REG_STATE) { 
     232 
     233            String msg_str = (String) m.obj; 
     234            lastRegStatus = msg_str; 
     235 
     236        } else if (m.what == MSG_TYPE.INCOMING_CALL) { 
     237 
     238            /* Incoming call */ 
     239            final MyCall call = (MyCall) m.obj; 
     240            CallOpParam prm = new CallOpParam(); 
     241 
     242            /* Only one call at anytime */ 
     243            if (currentCall != null) { 
     244                /* 
     245                prm.setStatusCode(pjsip_status_code.PJSIP_SC_BUSY_HERE); 
     246                try { 
     247                call.hangup(prm); 
     248                } catch (Exception e) {} 
     249                */ 
     250                // TODO: set status code 
     251                call.delete(); 
     252                return true; 
     253            } 
     254 
     255            /* Answer with ringing */ 
     256            prm.setStatusCode(pjsip_status_code.PJSIP_SC_RINGING); 
     257            try { 
     258                call.answer(prm); 
     259            } catch (Exception e) {} 
     260 
     261            currentCall = call; 
     262            showCallActivity(); 
     263 
     264        } else { 
     265 
     266            /* Message not handled */ 
     267            return false; 
     268 
     269        } 
     270 
     271        return true; 
     272    } 
     273 
     274 
     275    private void dlgAccountSetting() 
     276    { 
     277        LayoutInflater li = LayoutInflater.from(this); 
     278        View view = li.inflate(R.layout.dlg_account_config, null); 
     279 
     280        if (lastRegStatus.length()!=0) { 
     281            TextView tvInfo = (TextView)view.findViewById(R.id.textViewInfo); 
     282            tvInfo.setText("Last status: " + lastRegStatus); 
     283        } 
     284 
     285        AlertDialog.Builder adb = new AlertDialog.Builder(this); 
     286        adb.setView(view); 
     287        adb.setTitle("Account Settings"); 
     288 
     289        final EditText etId    = (EditText)view.findViewById(R.id.editTextId); 
     290        final EditText etReg   = (EditText)view.findViewById(R.id.editTextRegistrar); 
     291        final EditText etProxy = (EditText)view.findViewById(R.id.editTextProxy); 
     292        final EditText etUser  = (EditText)view.findViewById(R.id.editTextUsername); 
     293        final EditText etPass  = (EditText)view.findViewById(R.id.editTextPassword); 
     294 
     295        etId.   setText(accCfg.getIdUri()); 
     296        etReg.  setText(accCfg.getRegConfig().getRegistrarUri()); 
     297        StringVector proxies = accCfg.getSipConfig().getProxies(); 
     298        if (proxies.size() > 0) 
     299            etProxy.setText(proxies.get(0)); 
     300        else 
     301            etProxy.setText(""); 
     302        AuthCredInfoVector creds = accCfg.getSipConfig().getAuthCreds(); 
     303        if (creds.size() > 0) { 
     304            etUser. setText(creds.get(0).getUsername()); 
     305            etPass. setText(creds.get(0).getData()); 
     306        } else { 
     307            etUser. setText(""); 
     308            etPass. setText(""); 
     309        } 
     310 
     311        adb.setCancelable(false); 
     312        adb.setPositiveButton("OK", 
     313            new DialogInterface.OnClickListener() 
     314            { 
     315                public void onClick(DialogInterface dialog,int id) 
     316                { 
     317                    String acc_id        = etId.getText().toString(); 
     318                    String registrar = etReg.getText().toString(); 
     319                    String proxy         = etProxy.getText().toString(); 
     320                    String username  = etUser.getText().toString(); 
     321                    String password  = etPass.getText().toString(); 
     322 
     323                    accCfg.setIdUri(acc_id); 
     324                    accCfg.getRegConfig().setRegistrarUri(registrar); 
     325                    AuthCredInfoVector creds = accCfg.getSipConfig(). 
     326                                                            getAuthCreds(); 
     327                    creds.clear(); 
     328                    if (username.length() != 0) { 
     329                        creds.add(new AuthCredInfo("Digest", "*", username, 0, 
     330                                                   password)); 
     331                    } 
     332                    StringVector proxies = accCfg.getSipConfig().getProxies(); 
     333                    proxies.clear(); 
     334                    if (proxy.length() != 0) { 
     335                        proxies.add(proxy); 
     336                    } 
     337 
     338                    /* Enable ICE */ 
     339                    accCfg.getNatConfig().setIceEnabled(true); 
     340 
     341                    /* Finally */ 
     342                    lastRegStatus = ""; 
     343                    try { 
     344                        account.modify(accCfg); 
     345                    } catch (Exception e) {} 
     346                } 
     347            } 
     348        ); 
     349        adb.setNegativeButton("Cancel", 
     350            new DialogInterface.OnClickListener() 
     351            { 
     352                public void onClick(DialogInterface dialog,int id) 
     353                { 
     354                    dialog.cancel(); 
     355                } 
     356            } 
     357        ); 
     358 
     359        AlertDialog ad = adb.create(); 
     360        ad.show(); 
     361    } 
     362 
     363 
     364    public void makeCall(View view) 
     365    { 
     366        if (buddyListSelectedIdx == -1) 
     367            return; 
     368 
     369        /* Only one call at anytime */ 
     370        if (currentCall != null) { 
     371            return; 
     372        } 
     373 
     374        HashMap<String, String> item = (HashMap<String, String>) buddyListView. 
     375                                       getItemAtPosition(buddyListSelectedIdx); 
     376        String buddy_uri = item.get("uri"); 
     377 
     378        MyCall call = new MyCall(account, -1); 
     379        CallOpParam prm = new CallOpParam(true); 
     380 
     381        try { 
     382            call.makeCall(buddy_uri, prm); 
     383        } catch (Exception e) { 
     384            call.delete(); 
     385            return; 
     386        } 
     387 
     388        currentCall = call; 
     389        showCallActivity(); 
     390    } 
     391 
     392    private void dlgAddEditBuddy(BuddyConfig initial) 
     393    { 
     394        final BuddyConfig cfg = new BuddyConfig(); 
     395        final BuddyConfig old_cfg = initial; 
     396        final boolean is_add = initial == null; 
     397 
     398        LayoutInflater li = LayoutInflater.from(this); 
     399        View view = li.inflate(R.layout.dlg_add_buddy, null); 
     400 
     401        AlertDialog.Builder adb = new AlertDialog.Builder(this); 
     402        adb.setView(view); 
     403 
     404        final EditText etUri  = (EditText)view.findViewById(R.id.editTextUri); 
     405        final CheckBox cbSubs = (CheckBox)view.findViewById(R.id.checkBoxSubscribe); 
     406 
     407        if (is_add) { 
     408            adb.setTitle("Add Buddy"); 
     409        } else { 
     410            adb.setTitle("Edit Buddy"); 
     411            etUri. setText(initial.getUri()); 
     412            cbSubs.setChecked(initial.getSubscribe()); 
     413        } 
     414 
     415        adb.setCancelable(false); 
     416        adb.setPositiveButton("OK", 
     417            new DialogInterface.OnClickListener() 
     418            { 
     419                public void onClick(DialogInterface dialog,int id) 
     420                { 
     421                    cfg.setUri(etUri.getText().toString()); 
     422                    cfg.setSubscribe(cbSubs.isChecked()); 
     423 
     424                    if (is_add) { 
     425                        account.addBuddy(cfg); 
     426                        buddyList.add(putData(cfg.getUri(), "")); 
     427                        buddyListAdapter.notifyDataSetChanged(); 
     428                        buddyListSelectedIdx = -1; 
     429                    } else { 
     430                        if (!old_cfg.getUri().equals(cfg.getUri())) { 
     431                            account.delBuddy(buddyListSelectedIdx); 
     432                            account.addBuddy(cfg); 
     433                            buddyList.remove(buddyListSelectedIdx); 
     434                            buddyList.add(putData(cfg.getUri(), "")); 
     435                            buddyListAdapter.notifyDataSetChanged(); 
     436                            buddyListSelectedIdx = -1; 
     437                        } else if (old_cfg.getSubscribe() !=  
     438                                   cfg.getSubscribe()) 
     439                        { 
     440                            MyBuddy bud = account.buddyList.get( 
     441                                                        buddyListSelectedIdx); 
     442                            try { 
     443                                bud.subscribePresence(cfg.getSubscribe()); 
     444                            } catch (Exception e) {} 
    92445                        } 
    93                          
    94                     app.init(this, getFilesDir().getAbsolutePath()); 
     446                    } 
    95447                } 
    96                  
    97             if (app.accList.size() == 0) { 
    98                 accCfg = new AccountConfig(); 
    99                 accCfg.setIdUri("sip:localhost"); 
    100                 accCfg.getNatConfig().setIceEnabled(true); 
    101                 account = app.addAcc(accCfg); 
    102             } else { 
    103                 account = app.accList.get(0); 
    104                 accCfg = account.cfg; 
    105             } 
    106              
    107                 buddyList = new ArrayList<Map<String, String>>(); 
    108                 for (int i = 0; i < account.buddyList.size(); i++) { 
    109                         buddyList.add(putData(account.buddyList.get(i).cfg.getUri(), 
    110                                                                   account.buddyList.get(i).getStatusText())); 
     448            } 
     449        ); 
     450        adb.setNegativeButton("Cancel", 
     451            new DialogInterface.OnClickListener() 
     452            { 
     453                public void onClick(DialogInterface dialog,int id) { 
     454                    dialog.cancel(); 
    111455                } 
    112  
    113                 String[] from = { "uri", "status" }; 
    114             int[] to = { android.R.id.text1, android.R.id.text2 }; 
    115             buddyListAdapter = new SimpleAdapter(this, buddyList, android.R.layout.simple_list_item_2, from, to); 
    116              
    117                 buddyListView = (ListView) findViewById(R.id.listViewBuddy);; 
    118             buddyListView.setAdapter(buddyListAdapter); 
    119             buddyListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
    120                 @Override 
    121                 public void onItemClick(AdapterView<?> parent, final View view, 
    122                                 int position, long id)  
    123                 { 
    124                         view.setSelected(true); 
    125                         buddyListSelectedIdx = position; 
    126                 } 
    127             }); 
    128              
    129         } 
    130  
    131         @Override 
    132         public boolean onCreateOptionsMenu(Menu menu) { 
    133                 // Inflate the menu; this adds items to the action bar if it is present. 
    134                 getMenuInflater().inflate(R.menu.main, menu); 
    135                 return true; 
    136         } 
    137  
    138         @Override 
    139         public boolean onOptionsItemSelected(MenuItem item) { 
    140                 switch (item.getItemId()) { 
    141                 case R.id.action_acc_config: 
    142                         dlgAccountSetting(); 
     456            } 
     457        ); 
     458 
     459        AlertDialog ad = adb.create(); 
     460        ad.show(); 
     461    } 
     462 
     463    public void addBuddy(View view) 
     464    { 
     465        dlgAddEditBuddy(null); 
     466    } 
     467 
     468    public void editBuddy(View view) 
     469    { 
     470        if (buddyListSelectedIdx == -1) 
     471            return; 
     472 
     473        BuddyConfig old_cfg = account.buddyList.get(buddyListSelectedIdx).cfg; 
     474        dlgAddEditBuddy(old_cfg); 
     475    } 
     476 
     477    public void delBuddy(View view) { 
     478        if (buddyListSelectedIdx == -1) 
     479            return; 
     480 
     481        final HashMap<String, String> item = (HashMap<String, String>) 
     482                        buddyListView.getItemAtPosition(buddyListSelectedIdx); 
     483        String buddy_uri = item.get("uri"); 
     484 
     485        DialogInterface.OnClickListener ocl = 
     486                                        new DialogInterface.OnClickListener() 
     487        { 
     488            @Override 
     489            public void onClick(DialogInterface dialog, int which) 
     490            { 
     491                switch (which) { 
     492                    case DialogInterface.BUTTON_POSITIVE: 
     493                        account.delBuddy(buddyListSelectedIdx); 
     494                        buddyList.remove(item); 
     495                        buddyListAdapter.notifyDataSetChanged(); 
     496                        buddyListSelectedIdx = -1; 
    143497                        break; 
    144  
    145                 case R.id.action_quit: 
    146                         Message m = Message.obtain(handler, 0); 
    147                         m.sendToTarget(); 
    148                         break; 
    149                          
    150                 default: 
     498                    case DialogInterface.BUTTON_NEGATIVE: 
    151499                        break; 
    152500                } 
    153  
    154                 return true; 
    155         }        
    156  
    157         @Override 
    158         public boolean handleMessage(Message m) { 
    159                  
    160                 if (m.what == 0) { 
    161                          
    162                         app.deinit(); 
    163                         finish(); 
    164                         Runtime.getRuntime().gc(); 
    165                         android.os.Process.killProcess(android.os.Process.myPid()); 
    166                          
    167                 } else if (m.what == MSG_TYPE.CALL_STATE) { 
    168                          
    169                         CallInfo ci = (CallInfo) m.obj; 
    170                          
    171                         /* Forward the message to CallActivity */ 
    172                         if (CallActivity.handler_ != null) { 
    173                                 Message m2 = Message.obtain(CallActivity.handler_, MSG_TYPE.CALL_STATE, ci); 
    174                                 m2.sendToTarget(); 
    175                         } 
    176                          
    177                 } else if (m.what == MSG_TYPE.CALL_MEDIA_STATE) { 
    178                          
    179                         /* Forward the message to CallActivity */ 
    180                         if (CallActivity.handler_ != null) { 
    181                                 Message m2 = Message.obtain(CallActivity.handler_, MSG_TYPE.CALL_MEDIA_STATE, null); 
    182                                 m2.sendToTarget(); 
    183                         } 
    184                          
    185                 } else if (m.what == MSG_TYPE.BUDDY_STATE) { 
    186                          
    187                         MyBuddy buddy = (MyBuddy) m.obj; 
    188                         int idx = account.buddyList.indexOf(buddy); 
    189  
    190                         /* Update buddy status text, if buddy is valid and 
    191                          * the buddy lists in account and UI are sync-ed. 
    192                          */ 
    193                         if (idx >= 0 && account.buddyList.size() == buddyList.size()) { 
    194                                 buddyList.get(idx).put("status", buddy.getStatusText()); 
    195                                 buddyListAdapter.notifyDataSetChanged(); 
    196                                 // TODO: selection color/mark is gone after this, 
    197                                 //       dont know how to return it back. 
    198                                 //buddyListView.setSelection(buddyListSelectedIdx); 
    199                                 //buddyListView.performItemClick(buddyListView, buddyListSelectedIdx, 
    200                                 //                                                         buddyListView.getItemIdAtPosition(buddyListSelectedIdx)); 
    201                                  
    202                                 /* Return back Call activity */ 
    203                                 notifyCallState(currentCall); 
    204                         } 
    205                          
    206                 } else if (m.what == MSG_TYPE.REG_STATE) { 
    207                          
    208                         String msg_str = (String) m.obj; 
    209                         lastRegStatus = msg_str; 
    210                          
    211                 } else if (m.what == MSG_TYPE.INCOMING_CALL) { 
    212                          
    213                         /* Incoming call */ 
    214                         final MyCall call = (MyCall) m.obj; 
    215                         CallOpParam prm = new CallOpParam(); 
    216                          
    217                         /* Only one call at anytime */ 
    218                         if (currentCall != null) { 
    219                                 /* 
    220                                 prm.setStatusCode(pjsip_status_code.PJSIP_SC_BUSY_HERE); 
    221                                 try { 
    222                                         call.hangup(prm); 
    223                                 } catch (Exception e) {} 
    224                                 */ 
    225                                 // TODO: set status code 
    226                                 call.delete(); 
    227                                 return true; 
    228                         } 
    229  
    230                         /* Answer with ringing */ 
    231                         prm.setStatusCode(pjsip_status_code.PJSIP_SC_RINGING); 
    232                         try { 
    233                                 call.answer(prm); 
    234                         } catch (Exception e) {} 
    235                          
    236                         currentCall = call; 
    237                         showCallActivity(); 
    238  
    239                 } else { 
    240                          
    241                         /* Message not handled */ 
    242                         return false; 
    243                          
    244                 } 
    245                          
    246                 return true; 
    247         } 
    248          
    249  
    250         private void dlgAccountSetting() { 
    251                  
    252                 LayoutInflater li = LayoutInflater.from(this); 
    253                 View view = li.inflate(R.layout.dlg_account_config, null); 
    254                  
    255                 if (lastRegStatus.length()!=0) { 
    256                         TextView tvInfo = (TextView)view.findViewById(R.id.textViewInfo); 
    257                         tvInfo.setText("Last status: " + lastRegStatus); 
    258                 } 
    259  
    260                 AlertDialog.Builder adb = new AlertDialog.Builder(this); 
    261                 adb.setView(view); 
    262                 adb.setTitle("Account Settings"); 
    263  
    264                 final EditText etId    = (EditText)view.findViewById(R.id.editTextId); 
    265                 final EditText etReg   = (EditText)view.findViewById(R.id.editTextRegistrar); 
    266                 final EditText etProxy = (EditText)view.findViewById(R.id.editTextProxy); 
    267                 final EditText etUser  = (EditText)view.findViewById(R.id.editTextUsername); 
    268                 final EditText etPass  = (EditText)view.findViewById(R.id.editTextPassword); 
    269                  
    270                 etId.   setText(accCfg.getIdUri()); 
    271                 etReg.  setText(accCfg.getRegConfig().getRegistrarUri()); 
    272                 StringVector proxies = accCfg.getSipConfig().getProxies(); 
    273                 if (proxies.size() > 0) 
    274                         etProxy.setText(proxies.get(0)); 
    275                 else 
    276                         etProxy.setText(""); 
    277                 AuthCredInfoVector creds = accCfg.getSipConfig().getAuthCreds(); 
    278                 if (creds.size() > 0) { 
    279                         etUser. setText(creds.get(0).getUsername()); 
    280                         etPass. setText(creds.get(0).getData()); 
    281                 } else { 
    282                         etUser. setText(""); 
    283                         etPass. setText(""); 
    284                 } 
    285                  
    286                 adb.setCancelable(false); 
    287                 adb.setPositiveButton("OK", 
    288                           new DialogInterface.OnClickListener() { 
    289                             public void onClick(DialogInterface dialog,int id) { 
    290                                 String acc_id    = etId.getText().toString(); 
    291                                 String registrar = etReg.getText().toString(); 
    292                                 String proxy     = etProxy.getText().toString(); 
    293                                 String username  = etUser.getText().toString(); 
    294                                 String password  = etPass.getText().toString(); 
    295                                  
    296                                 accCfg.setIdUri(acc_id); 
    297                                 accCfg.getRegConfig().setRegistrarUri(registrar); 
    298                                         AuthCredInfoVector creds = accCfg.getSipConfig().getAuthCreds(); 
    299                                         creds.clear(); 
    300                                         if (username.length() != 0) { 
    301                                                 creds.add(new AuthCredInfo("Digest", "*", username, 0, password)); 
    302                                         } 
    303                                         StringVector proxies = accCfg.getSipConfig().getProxies(); 
    304                                         proxies.clear(); 
    305                                         if (proxy.length() != 0) { 
    306                                                 proxies.add(proxy); 
    307                                         } 
    308                                          
    309                                 /* Enable ICE */ 
    310                                 accCfg.getNatConfig().setIceEnabled(true); 
    311                                  
    312                                         /* Finally */ 
    313                                         lastRegStatus = ""; 
    314                                         try { 
    315                                                 account.modify(accCfg); 
    316                                         } catch (Exception e) {} 
    317                             } 
    318                           }); 
    319                 adb.setNegativeButton("Cancel", 
    320                           new DialogInterface.OnClickListener() { 
    321                             public void onClick(DialogInterface dialog,int id) { 
    322                                 dialog.cancel(); 
    323                             } 
    324                           }); 
    325  
    326                 AlertDialog ad = adb.create(); 
    327                 ad.show(); 
    328         } 
    329          
    330          
    331         public void makeCall(View view) { 
    332                 if (buddyListSelectedIdx == -1) 
    333                         return; 
    334                  
    335                 /* Only one call at anytime */ 
    336                 if (currentCall != null) { 
    337                         return; 
    338                 } 
    339                  
    340                 HashMap<String, String> item = (HashMap<String, String>) buddyListView.getItemAtPosition(buddyListSelectedIdx); 
    341                 String buddy_uri = item.get("uri"); 
    342                  
    343                 MyCall call = new MyCall(account, -1); 
    344                 CallOpParam prm = new CallOpParam(true); 
    345  
    346                 try { 
    347                         call.makeCall(buddy_uri, prm); 
    348                 } catch (Exception e) { 
    349                         call.delete(); 
    350                         return; 
    351                 } 
    352                  
    353                 currentCall = call; 
    354                 showCallActivity(); 
    355         } 
    356  
    357         private void dlgAddEditBuddy(BuddyConfig initial) { 
    358                 final BuddyConfig cfg = new BuddyConfig(); 
    359                 final BuddyConfig old_cfg = initial; 
    360                 final boolean is_add = initial == null; 
    361                  
    362                 LayoutInflater li = LayoutInflater.from(this); 
    363                 View view = li.inflate(R.layout.dlg_add_buddy, null); 
    364  
    365                 AlertDialog.Builder adb = new AlertDialog.Builder(this); 
    366                 adb.setView(view); 
    367  
    368                 final EditText etUri    = (EditText)view.findViewById(R.id.editTextUri); 
    369                 final CheckBox cbSubs  = (CheckBox)view.findViewById(R.id.checkBoxSubscribe); 
    370  
    371                 if (is_add) { 
    372                         adb.setTitle("Add Buddy"); 
    373                 } else { 
    374                         adb.setTitle("Edit Buddy"); 
    375                         etUri. setText(initial.getUri()); 
    376                         cbSubs.setChecked(initial.getSubscribe()); 
    377                 } 
    378  
    379                 adb.setCancelable(false); 
    380                 adb.setPositiveButton("OK", 
    381                           new DialogInterface.OnClickListener() { 
    382                             public void onClick(DialogInterface dialog,int id) { 
    383                                 cfg.setUri(etUri.getText().toString()); 
    384                                 cfg.setSubscribe(cbSubs.isChecked()); 
    385                                  
    386                                 if (is_add) { 
    387                                         account.addBuddy(cfg); 
    388                                                 buddyList.add(putData(cfg.getUri(), "")); 
    389                                                 buddyListAdapter.notifyDataSetChanged(); 
    390                                                 buddyListSelectedIdx = -1; 
    391                                 } else { 
    392                                         if (!old_cfg.getUri().equals(cfg.getUri())) { 
    393                                                 account.delBuddy(buddyListSelectedIdx); 
    394                                                 account.addBuddy(cfg); 
    395                                                         buddyList.remove(buddyListSelectedIdx); 
    396                                                         buddyList.add(putData(cfg.getUri(), "")); 
    397                                                 buddyListAdapter.notifyDataSetChanged(); 
    398                                                 buddyListSelectedIdx = -1; 
    399                                         } else if (old_cfg.getSubscribe() != cfg.getSubscribe()) { 
    400                                                 MyBuddy bud = account.buddyList.get(buddyListSelectedIdx); 
    401                                                         try { 
    402                                                         bud.subscribePresence(cfg.getSubscribe()); 
    403                                                         } catch (Exception e) {} 
    404                                         } 
    405                                 } 
    406                             } 
    407                           }); 
    408                 adb.setNegativeButton("Cancel", 
    409                           new DialogInterface.OnClickListener() { 
    410                             public void onClick(DialogInterface dialog,int id) { 
    411                                 dialog.cancel(); 
    412                             } 
    413                           }); 
    414  
    415                 AlertDialog ad = adb.create(); 
    416                 ad.show(); 
    417         } 
    418          
    419         public void addBuddy(View view) { 
    420                 dlgAddEditBuddy(null); 
    421         } 
    422  
    423         public void editBuddy(View view) { 
    424                 if (buddyListSelectedIdx == -1) 
    425                         return; 
    426                  
    427                 BuddyConfig old_cfg = account.buddyList.get(buddyListSelectedIdx).cfg; 
    428                 dlgAddEditBuddy(old_cfg); 
    429         } 
    430          
    431         public void delBuddy(View view) { 
    432                 if (buddyListSelectedIdx == -1) 
    433                         return; 
    434                  
    435                 final HashMap<String, String> item = (HashMap<String, String>) buddyListView.getItemAtPosition(buddyListSelectedIdx); 
    436                 String buddy_uri = item.get("uri"); 
    437                  
    438                 DialogInterface.OnClickListener ocl = new DialogInterface.OnClickListener() { 
    439                     @Override 
    440                     public void onClick(DialogInterface dialog, int which) { 
    441                         switch (which) { 
    442                         case DialogInterface.BUTTON_POSITIVE: 
    443                                 account.delBuddy(buddyListSelectedIdx); 
    444                                 buddyList.remove(item); 
    445                                 buddyListAdapter.notifyDataSetChanged(); 
    446                                 buddyListSelectedIdx = -1; 
    447                             break; 
    448                         case DialogInterface.BUTTON_NEGATIVE: 
    449                             break; 
    450                         } 
    451                     } 
    452                 }; 
    453  
    454                 AlertDialog.Builder adb = new AlertDialog.Builder(this); 
    455                 adb.setTitle(buddy_uri); 
    456                 adb.setMessage("\nDelete this buddy?\n"); 
    457                 adb.setPositiveButton("Yes", ocl); 
    458                 adb.setNegativeButton("No", ocl); 
    459                 adb.show(); 
    460         } 
    461          
    462          
    463         /* 
    464          * === MyAppObserver === 
    465          *  
    466          * As we cannot do UI from worker thread, the callbacks mostly just send 
    467          * a message to UI/main thread. 
    468          */ 
    469          
    470         public void notifyIncomingCall(MyCall call) { 
    471                 Message m = Message.obtain(handler, MSG_TYPE.INCOMING_CALL, call); 
    472                 m.sendToTarget(); 
    473         } 
    474  
    475         public void notifyRegState(pjsip_status_code code, String reason, int expiration) { 
    476                 String msg_str = ""; 
    477                 if (expiration == 0) 
    478                         msg_str += "Unregistration"; 
    479                 else 
    480                         msg_str += "Registration"; 
    481                  
    482                 if (code.swigValue()/100 == 2) 
    483                         msg_str += " successful"; 
    484                 else 
    485                         msg_str += " failed: " + reason; 
    486                  
    487                 Message m = Message.obtain(handler, MSG_TYPE.REG_STATE, msg_str); 
    488                 m.sendToTarget(); 
    489         } 
    490          
    491         public void notifyCallState(MyCall call) { 
    492                 if (currentCall == null || call.getId() != currentCall.getId()) 
    493                         return; 
    494                  
    495                 CallInfo ci; 
    496                 try { 
    497                         ci = call.getInfo(); 
    498                 } catch (Exception e) { 
    499                         ci = null; 
    500                 } 
    501                 Message m = Message.obtain(handler, MSG_TYPE.CALL_STATE, ci); 
    502                 m.sendToTarget(); 
    503                  
    504                 if (ci != null && 
    505                         ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) 
    506                 { 
    507                         currentCall = null; 
    508                 } 
    509         } 
    510          
    511         public void notifyCallMediaState(MyCall call) { 
    512                 Message m = Message.obtain(handler, MSG_TYPE.CALL_MEDIA_STATE, null); 
    513                 m.sendToTarget(); 
    514         } 
    515          
    516         public void notifyBuddyState(MyBuddy buddy) { 
    517                 Message m = Message.obtain(handler, MSG_TYPE.BUDDY_STATE, buddy); 
    518                 m.sendToTarget(); 
    519         } 
    520  
    521         /* === end of MyAppObserver ==== */ 
     501            } 
     502        }; 
     503 
     504        AlertDialog.Builder adb = new AlertDialog.Builder(this); 
     505        adb.setTitle(buddy_uri); 
     506        adb.setMessage("\nDelete this buddy?\n"); 
     507        adb.setPositiveButton("Yes", ocl); 
     508        adb.setNegativeButton("No", ocl); 
     509        adb.show(); 
     510    } 
     511 
     512 
     513    /* 
     514    * === MyAppObserver === 
     515    *  
     516    * As we cannot do UI from worker thread, the callbacks mostly just send 
     517    * a message to UI/main thread. 
     518    */ 
     519 
     520    public void notifyIncomingCall(MyCall call) 
     521    { 
     522        Message m = Message.obtain(handler, MSG_TYPE.INCOMING_CALL, call); 
     523        m.sendToTarget(); 
     524    } 
     525 
     526    public void notifyRegState(pjsip_status_code code, String reason, 
     527                               int expiration) 
     528    { 
     529        String msg_str = ""; 
     530        if (expiration == 0) 
     531            msg_str += "Unregistration"; 
     532        else 
     533            msg_str += "Registration"; 
     534 
     535        if (code.swigValue()/100 == 2) 
     536            msg_str += " successful"; 
     537        else 
     538            msg_str += " failed: " + reason; 
     539 
     540        Message m = Message.obtain(handler, MSG_TYPE.REG_STATE, msg_str); 
     541        m.sendToTarget(); 
     542    } 
     543 
     544    public void notifyCallState(MyCall call) 
     545    { 
     546        if (currentCall == null || call.getId() != currentCall.getId()) 
     547            return; 
     548 
     549        CallInfo ci; 
     550        try { 
     551            ci = call.getInfo(); 
     552        } catch (Exception e) { 
     553            ci = null; 
     554        } 
     555        Message m = Message.obtain(handler, MSG_TYPE.CALL_STATE, ci); 
     556        m.sendToTarget(); 
     557 
     558        if (ci != null && 
     559            ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) 
     560        { 
     561            currentCall = null; 
     562        } 
     563    } 
     564 
     565    public void notifyCallMediaState(MyCall call) 
     566    { 
     567        Message m = Message.obtain(handler, MSG_TYPE.CALL_MEDIA_STATE, null); 
     568        m.sendToTarget(); 
     569    } 
     570 
     571    public void notifyBuddyState(MyBuddy buddy) 
     572    { 
     573        Message m = Message.obtain(handler, MSG_TYPE.BUDDY_STATE, buddy); 
     574        m.sendToTarget(); 
     575    } 
     576 
     577    /* === end of MyAppObserver ==== */ 
    522578 
    523579} 
  • pjproject/trunk/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java

    r5016 r5017  
    2626 
    2727/* Interface to separate UI & engine a bit better */ 
    28 interface MyAppObserver { 
    29         abstract void notifyRegState(pjsip_status_code code, String reason, int expiration); 
    30         abstract void notifyIncomingCall(MyCall call); 
    31         abstract void notifyCallState(MyCall call); 
    32         abstract void notifyCallMediaState(MyCall call); 
    33         abstract void notifyBuddyState(MyBuddy buddy); 
    34 } 
    35  
    36  
    37 class MyLogWriter extends LogWriter { 
    38         @Override 
    39         public void write(LogEntry entry) { 
    40                 System.out.println(entry.getMsg()); 
    41         } 
    42 } 
    43  
    44  
    45 class MyCall extends Call { 
    46         public VideoWindow vidWin; 
    47          
    48         MyCall(MyAccount acc, int call_id) { 
    49                 super(acc, call_id); 
    50                 vidWin = null; 
    51         } 
    52  
    53         @Override 
    54         public void onCallState(OnCallStateParam prm) { 
    55                 MyApp.observer.notifyCallState(this); 
     28interface MyAppObserver 
     29{ 
     30    abstract void notifyRegState(pjsip_status_code code, String reason, 
     31                                 int expiration); 
     32    abstract void notifyIncomingCall(MyCall call); 
     33    abstract void notifyCallState(MyCall call); 
     34    abstract void notifyCallMediaState(MyCall call); 
     35    abstract void notifyBuddyState(MyBuddy buddy); 
     36} 
     37 
     38 
     39class MyLogWriter extends LogWriter 
     40{ 
     41    @Override 
     42    public void write(LogEntry entry) 
     43    { 
     44        System.out.println(entry.getMsg()); 
     45    } 
     46} 
     47 
     48 
     49class MyCall extends Call 
     50{ 
     51    public VideoWindow vidWin; 
     52 
     53    MyCall(MyAccount acc, int call_id) 
     54    { 
     55        super(acc, call_id); 
     56        vidWin = null; 
     57    } 
     58 
     59    @Override 
     60    public void onCallState(OnCallStateParam prm) 
     61    { 
     62            MyApp.observer.notifyCallState(this); 
     63            try { 
     64                CallInfo ci = getInfo(); 
     65                if (ci.getState() ==  
     66                    pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) 
     67                { 
     68                    this.delete(); 
     69                } 
     70            } catch (Exception e) { 
     71                return; 
     72            } 
     73    } 
     74 
     75    @Override 
     76    public void onCallMediaState(OnCallMediaStateParam prm) 
     77    { 
     78        CallInfo ci; 
     79        try { 
     80            ci = getInfo(); 
     81        } catch (Exception e) { 
     82            return; 
     83        } 
     84 
     85        CallMediaInfoVector cmiv = ci.getMedia(); 
     86 
     87        for (int i = 0; i < cmiv.size(); i++) { 
     88            CallMediaInfo cmi = cmiv.get(i); 
     89            if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO && 
     90                (cmi.getStatus() ==  
     91                        pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE || 
     92                 cmi.getStatus() ==  
     93                        pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD)) 
     94            { 
     95                // unfortunately, on Java too, the returned Media cannot be 
     96                // downcasted to AudioMedia  
     97                Media m = getMedia(i); 
     98                AudioMedia am = AudioMedia.typecastFromMedia(m); 
     99 
     100                // connect ports 
    56101                try { 
    57                         CallInfo ci = getInfo(); 
    58                         if (ci.getState() == pjsip_inv_state.PJSIP_INV_STATE_DISCONNECTED) { 
    59                                 this.delete(); 
    60                         } 
     102                    MyApp.ep.audDevManager().getCaptureDevMedia(). 
     103                                                            startTransmit(am); 
     104                    am.startTransmit(MyApp.ep.audDevManager(). 
     105                                     getPlaybackDevMedia()); 
    61106                } catch (Exception e) { 
    62                         return; 
     107                    continue; 
    63108                } 
    64         } 
    65          
    66         @Override 
    67         public void onCallMediaState(OnCallMediaStateParam prm) { 
    68                 CallInfo ci; 
     109            } else if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_VIDEO && 
     110                       cmi.getStatus() ==  
     111                            pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE && 
     112                       cmi.getVideoIncomingWindowId() != pjsua2.INVALID_ID) 
     113            { 
     114                vidWin = new VideoWindow(cmi.getVideoIncomingWindowId()); 
     115            } 
     116        } 
     117 
     118        MyApp.observer.notifyCallMediaState(this); 
     119    } 
     120} 
     121 
     122 
     123class MyAccount extends Account 
     124{ 
     125    public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>(); 
     126    public AccountConfig cfg; 
     127 
     128    MyAccount(AccountConfig config) 
     129    { 
     130        super(); 
     131        cfg = config; 
     132    } 
     133 
     134    public MyBuddy addBuddy(BuddyConfig bud_cfg) 
     135    { 
     136        /* Create Buddy */ 
     137        MyBuddy bud = new MyBuddy(bud_cfg); 
     138        try { 
     139            bud.create(this, bud_cfg); 
     140        } catch (Exception e) { 
     141            bud.delete(); 
     142            bud = null; 
     143        } 
     144 
     145        if (bud != null) { 
     146            buddyList.add(bud); 
     147            if (bud_cfg.getSubscribe()) 
    69148                try { 
    70                         ci = getInfo(); 
    71                 } catch (Exception e) { 
    72                         return; 
     149                    bud.subscribePresence(true); 
     150            } catch (Exception e) {} 
     151        } 
     152 
     153        return bud; 
     154    } 
     155 
     156    public void delBuddy(MyBuddy buddy) 
     157    { 
     158        buddyList.remove(buddy); 
     159        buddy.delete(); 
     160    } 
     161 
     162    public void delBuddy(int index) 
     163    { 
     164        MyBuddy bud = buddyList.get(index); 
     165        buddyList.remove(index); 
     166        bud.delete(); 
     167    } 
     168 
     169    @Override 
     170    public void onRegState(OnRegStateParam prm) 
     171    { 
     172        MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(), 
     173                                      prm.getExpiration()); 
     174    } 
     175 
     176    @Override 
     177    public void onIncomingCall(OnIncomingCallParam prm) 
     178    { 
     179        System.out.println("======== Incoming call ======== "); 
     180        MyCall call = new MyCall(this, prm.getCallId()); 
     181        MyApp.observer.notifyIncomingCall(call); 
     182    } 
     183 
     184    @Override 
     185    public void onInstantMessage(OnInstantMessageParam prm) 
     186    { 
     187        System.out.println("======== Incoming pager ======== "); 
     188        System.out.println("From     : " + prm.getFromUri()); 
     189        System.out.println("To       : " + prm.getToUri()); 
     190        System.out.println("Contact  : " + prm.getContactUri()); 
     191        System.out.println("Mimetype : " + prm.getContentType()); 
     192        System.out.println("Body     : " + prm.getMsgBody()); 
     193    } 
     194} 
     195 
     196 
     197class MyBuddy extends Buddy 
     198{ 
     199    public BuddyConfig cfg; 
     200 
     201    MyBuddy(BuddyConfig config) 
     202    { 
     203        super(); 
     204        cfg = config; 
     205    } 
     206 
     207    String getStatusText() 
     208    { 
     209        BuddyInfo bi; 
     210 
     211        try { 
     212            bi = getInfo(); 
     213        } catch (Exception e) { 
     214            return "?"; 
     215        } 
     216 
     217        String status = ""; 
     218        if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) { 
     219            if (bi.getPresStatus().getStatus() == 
     220                pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE) 
     221            { 
     222                status = bi.getPresStatus().getStatusText(); 
     223                if (status == null || status.length()==0) { 
     224                    status = "Online"; 
    73225                } 
    74                  
    75                 CallMediaInfoVector cmiv = ci.getMedia(); 
    76                  
    77                 for (int i = 0; i < cmiv.size(); i++) { 
    78                         CallMediaInfo cmi = cmiv.get(i); 
    79                         if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO && 
    80                             (cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE || 
    81                              cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_REMOTE_HOLD)) 
    82                         { 
    83                                 // unfortunately, on Java too, the returned Media cannot be downcasted to AudioMedia  
    84                                 Media m = getMedia(i); 
    85                                 AudioMedia am = AudioMedia.typecastFromMedia(m); 
    86                                  
    87                                 // connect ports 
    88                                 try { 
    89                                         MyApp.ep.audDevManager().getCaptureDevMedia().startTransmit(am); 
    90                                         am.startTransmit(MyApp.ep.audDevManager().getPlaybackDevMedia()); 
    91                                 } catch (Exception e) { 
    92                                         continue; 
    93                                 } 
    94                         } else if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_VIDEO && 
    95                                        cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE && 
    96                                        cmi.getVideoIncomingWindowId() != pjsua2.INVALID_ID) 
    97                         { 
    98                                 vidWin = new VideoWindow(cmi.getVideoIncomingWindowId()); 
    99                         } 
    100                 } 
    101                  
    102                 MyApp.observer.notifyCallMediaState(this); 
    103         } 
    104 } 
    105  
    106  
    107 class MyAccount extends Account { 
    108         public ArrayList<MyBuddy> buddyList = new ArrayList<MyBuddy>(); 
    109         public AccountConfig cfg; 
    110          
    111         MyAccount(AccountConfig config) { 
    112                 super(); 
    113                 cfg = config; 
    114         } 
    115          
    116         public MyBuddy addBuddy(BuddyConfig bud_cfg) 
    117         { 
    118                 /* Create Buddy */ 
    119                 MyBuddy bud = new MyBuddy(bud_cfg); 
    120                 try { 
    121                         bud.create(this, bud_cfg); 
    122                 } catch (Exception e) { 
    123                         bud.delete(); 
    124                         bud = null; 
    125                 } 
    126                  
    127                 if (bud != null) { 
    128                         buddyList.add(bud); 
    129                         if (bud_cfg.getSubscribe()) 
    130                                 try { 
    131                                         bud.subscribePresence(true); 
    132                                 } catch (Exception e) {} 
    133                 } 
    134                  
    135                 return bud; 
    136         } 
    137          
    138         public void delBuddy(MyBuddy buddy) { 
    139                 buddyList.remove(buddy); 
    140                 buddy.delete(); 
    141         } 
    142          
    143         public void delBuddy(int index) { 
    144                 MyBuddy bud = buddyList.get(index); 
    145                 buddyList.remove(index); 
    146                 bud.delete(); 
    147         } 
    148          
    149         @Override 
    150         public void onRegState(OnRegStateParam prm) { 
    151                 MyApp.observer.notifyRegState(prm.getCode(), prm.getReason(), prm.getExpiration()); 
    152         } 
    153  
    154         @Override 
    155         public void onIncomingCall(OnIncomingCallParam prm) { 
    156                 System.out.println("======== Incoming call ======== "); 
    157                 MyCall call = new MyCall(this, prm.getCallId()); 
    158                 MyApp.observer.notifyIncomingCall(call); 
    159         } 
    160          
    161         @Override 
    162         public void onInstantMessage(OnInstantMessageParam prm) { 
    163                 System.out.println("======== Incoming pager ======== "); 
    164                 System.out.println("From                : " + prm.getFromUri()); 
    165                 System.out.println("To                  : " + prm.getToUri()); 
    166                 System.out.println("Contact             : " + prm.getContactUri()); 
    167                 System.out.println("Mimetype    : " + prm.getContentType()); 
    168                 System.out.println("Body                : " + prm.getMsgBody()); 
    169         } 
    170 } 
    171  
    172  
    173 class MyBuddy extends Buddy { 
    174         public BuddyConfig cfg; 
    175          
    176         MyBuddy(BuddyConfig config) { 
    177                 super(); 
    178                 cfg = config; 
    179         } 
    180          
    181         String getStatusText() { 
    182                 BuddyInfo bi; 
    183                  
    184                 try { 
    185                         bi = getInfo(); 
    186                 } catch (Exception e) { 
    187                         return "?"; 
    188                 } 
    189                  
    190                 String status = ""; 
    191                 if (bi.getSubState() == pjsip_evsub_state.PJSIP_EVSUB_STATE_ACTIVE) { 
    192                         if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_ONLINE) { 
    193                                 status = bi.getPresStatus().getStatusText(); 
    194                                 if (status == null || status.length()==0) { 
    195                                         status = "Online"; 
    196                                 } 
    197                         } else if (bi.getPresStatus().getStatus() == pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE) { 
    198                                 status = "Offline"; 
    199                         } else { 
    200                                 status = "Unknown"; 
    201                         } 
    202                 } 
    203                 return status; 
    204         } 
    205  
    206         @Override 
    207         public void onBuddyState() { 
    208                 MyApp.observer.notifyBuddyState(this); 
    209         } 
    210          
    211 } 
    212  
    213  
    214 class MyAccountConfig { 
    215         public AccountConfig accCfg = new AccountConfig(); 
    216         public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>(); 
    217          
    218         public void readObject(ContainerNode node) { 
    219                 try { 
    220                         ContainerNode acc_node = node.readContainer("Account"); 
    221                         accCfg.readObject(acc_node); 
    222                         ContainerNode buddies_node = acc_node.readArray("buddies"); 
    223                         buddyCfgs.clear(); 
    224                         while (buddies_node.hasUnread()) { 
    225                                 BuddyConfig bud_cfg = new BuddyConfig();  
    226                                 bud_cfg.readObject(buddies_node); 
    227                                 buddyCfgs.add(bud_cfg); 
    228                         } 
    229                 } catch (Exception e) {} 
    230         } 
    231          
    232         public void writeObject(ContainerNode node) { 
    233                 try { 
    234                         ContainerNode acc_node = node.writeNewContainer("Account"); 
    235                         accCfg.writeObject(acc_node); 
    236                         ContainerNode buddies_node = acc_node.writeNewArray("buddies"); 
    237                         for (int j = 0; j < buddyCfgs.size(); j++) { 
    238                                 buddyCfgs.get(j).writeObject(buddies_node); 
    239                         } 
    240                 } catch (Exception e) {} 
    241         } 
     226            } else if (bi.getPresStatus().getStatus() ==  
     227                       pjsua_buddy_status.PJSUA_BUDDY_STATUS_OFFLINE) 
     228            { 
     229                status = "Offline"; 
     230            } else { 
     231                status = "Unknown"; 
     232            } 
     233        } 
     234        return status; 
     235    } 
     236 
     237    @Override 
     238    public void onBuddyState() 
     239    { 
     240        MyApp.observer.notifyBuddyState(this); 
     241    } 
     242 
     243} 
     244 
     245 
     246class MyAccountConfig 
     247{ 
     248    public AccountConfig accCfg = new AccountConfig(); 
     249    public ArrayList<BuddyConfig> buddyCfgs = new ArrayList<BuddyConfig>(); 
     250 
     251    public void readObject(ContainerNode node) 
     252    { 
     253        try { 
     254            ContainerNode acc_node = node.readContainer("Account"); 
     255            accCfg.readObject(acc_node); 
     256            ContainerNode buddies_node = acc_node.readArray("buddies"); 
     257            buddyCfgs.clear(); 
     258            while (buddies_node.hasUnread()) { 
     259                BuddyConfig bud_cfg = new BuddyConfig();  
     260                bud_cfg.readObject(buddies_node); 
     261                buddyCfgs.add(bud_cfg); 
     262            } 
     263        } catch (Exception e) {} 
     264    } 
     265 
     266    public void writeObject(ContainerNode node) 
     267    { 
     268        try { 
     269            ContainerNode acc_node = node.writeNewContainer("Account"); 
     270            accCfg.writeObject(acc_node); 
     271            ContainerNode buddies_node = acc_node.writeNewArray("buddies"); 
     272            for (int j = 0; j < buddyCfgs.size(); j++) { 
     273                buddyCfgs.get(j).writeObject(buddies_node); 
     274            } 
     275        } catch (Exception e) {} 
     276    } 
    242277} 
    243278 
    244279 
    245280class MyApp { 
    246         static { 
    247                 try{ 
    248                     System.loadLibrary("openh264"); 
    249                     System.loadLibrary("yuv"); 
    250                 } catch (UnsatisfiedLinkError e) { 
    251                     System.out.println("UnsatisfiedLinkError: " + e.getMessage()); 
    252                     System.out.println("This could be safely ignored if you " + 
    253                                        "don't need video."); 
    254                 } 
    255                 System.loadLibrary("pjsua2"); 
    256                 System.out.println("Library loaded"); 
    257         } 
    258          
    259         public static Endpoint ep = new Endpoint(); 
    260         public static MyAppObserver observer; 
    261         public ArrayList<MyAccount> accList = new ArrayList<MyAccount>(); 
    262  
    263         private ArrayList<MyAccountConfig> accCfgs = new ArrayList<MyAccountConfig>(); 
    264         private EpConfig epConfig = new EpConfig(); 
    265         private TransportConfig sipTpConfig = new TransportConfig(); 
    266         private String appDir; 
    267          
    268         /* Maintain reference to log writer to avoid premature cleanup by GC */ 
    269         private MyLogWriter logWriter; 
    270  
    271         private final String configName = "pjsua2.json"; 
    272         private final int SIP_PORT  = 6000; 
    273         private final int LOG_LEVEL = 4; 
    274          
    275         public void init(MyAppObserver obs, String app_dir) { 
    276                 init(obs, app_dir, false); 
    277         } 
    278          
    279         public void init(MyAppObserver obs, String app_dir, boolean own_worker_thread) { 
    280                 observer = obs; 
    281                 appDir = app_dir; 
    282                  
    283                 /* Create endpoint */ 
    284                 try { 
    285                         ep.libCreate(); 
    286                 } catch (Exception e) { 
    287                         return; 
    288                 } 
    289                          
    290                  
    291                 /* Load config */ 
    292                 String configPath = appDir + "/" + configName; 
    293                 File f = new File(configPath); 
    294                 if (f.exists()) { 
    295                         loadConfig(configPath); 
    296                 } else { 
    297                         /* Set 'default' values */ 
    298                         sipTpConfig.setPort(SIP_PORT); 
    299                 } 
    300                  
    301                 /* Override log level setting */ 
    302                 epConfig.getLogConfig().setLevel(LOG_LEVEL); 
    303                 epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL); 
    304                  
    305                 /* Set log config. */ 
    306                 LogConfig log_cfg = epConfig.getLogConfig(); 
    307                 logWriter = new MyLogWriter(); 
    308                 log_cfg.setWriter(logWriter); 
    309                 log_cfg.setDecor(log_cfg.getDecor() &  
    310                                                  ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() |  
    311                                                    pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue())); 
    312                  
    313                 /* Set ua config. */ 
    314                 UaConfig ua_cfg = epConfig.getUaConfig(); 
    315                 ua_cfg.setUserAgent("Pjsua2 Android " + ep.libVersion().getFull()); 
    316                 StringVector stun_servers = new StringVector(); 
    317                 stun_servers.add("stun.pjsip.org"); 
    318                 ua_cfg.setStunServer(stun_servers); 
    319                 if (own_worker_thread) { 
    320                         ua_cfg.setThreadCnt(0); 
    321                         ua_cfg.setMainThreadOnly(true); 
    322                 } 
    323                  
    324                 /* Init endpoint */ 
    325                 try { 
    326                         ep.libInit(epConfig); 
    327                 } catch (Exception e) { 
    328                         return; 
    329                 } 
    330                  
    331                 /* Create transports. */ 
    332                 try { 
    333                         ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, sipTpConfig); 
    334                 } catch (Exception e) { 
    335                         System.out.println(e); 
    336                 } 
    337  
    338                 try { 
    339                         ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP, sipTpConfig); 
    340                 } catch (Exception e) { 
    341                         System.out.println(e); 
    342                 } 
    343                  
    344                 /* Create accounts. */ 
    345                 for (int i = 0; i < accCfgs.size(); i++) { 
    346                         MyAccountConfig my_cfg = accCfgs.get(i); 
    347                         MyAccount acc = addAcc(my_cfg.accCfg); 
    348                         if (acc == null) 
    349                                 continue; 
    350                          
    351                         /* Add Buddies */ 
    352                         for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) { 
    353                                 BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j); 
    354                                 acc.addBuddy(bud_cfg); 
    355                         } 
    356                 } 
    357  
    358                 /* Start. */ 
    359                 try { 
    360                         ep.libStart(); 
    361                 } catch (Exception e) { 
    362                         return; 
    363                 } 
    364         } 
    365          
    366         public MyAccount addAcc(AccountConfig cfg) { 
    367                 MyAccount acc = new MyAccount(cfg); 
    368                 try { 
    369                         acc.create(cfg); 
    370                 } catch (Exception e) { 
    371                         acc = null; 
    372                         return null; 
    373                 } 
    374                  
    375                 accList.add(acc); 
    376                 return acc; 
    377         } 
    378          
    379         public void delAcc(MyAccount acc) { 
    380                 accList.remove(acc); 
    381         } 
    382          
    383         private void loadConfig(String filename) { 
    384                 JsonDocument json = new JsonDocument(); 
    385                  
    386                 try { 
    387                         /* Load file */ 
    388                         json.loadFile(filename); 
    389                         ContainerNode root = json.getRootContainer(); 
    390                          
    391                         /* Read endpoint config */ 
    392                         epConfig.readObject(root); 
    393                          
    394                         /* Read transport config */ 
    395                         ContainerNode tp_node = root.readContainer("SipTransport"); 
    396                         sipTpConfig.readObject(tp_node); 
    397                          
    398                         /* Read account configs */ 
    399                         accCfgs.clear(); 
    400                         ContainerNode accs_node = root.readArray("accounts"); 
    401                         while (accs_node.hasUnread()) { 
    402                                 MyAccountConfig acc_cfg = new MyAccountConfig(); 
    403                                 acc_cfg.readObject(accs_node); 
    404                                 accCfgs.add(acc_cfg); 
    405                         } 
    406                 } catch (Exception e) { 
    407                         System.out.println(e); 
    408                 } 
    409                  
    410                 /* Force delete json now, as I found that Java somehow destroys it 
    411                  * after lib has been destroyed and from non-registered thread. 
    412                  */ 
    413                 json.delete(); 
    414         } 
    415  
    416         private void buildAccConfigs() { 
    417                 /* Sync accCfgs from accList */ 
    418                 accCfgs.clear(); 
    419                 for (int i = 0; i < accList.size(); i++) { 
    420                         MyAccount acc = accList.get(i); 
    421                         MyAccountConfig my_acc_cfg = new MyAccountConfig(); 
    422                         my_acc_cfg.accCfg = acc.cfg; 
    423                          
    424                         my_acc_cfg.buddyCfgs.clear(); 
    425                         for (int j = 0; j < acc.buddyList.size(); j++) { 
    426                                 MyBuddy bud = acc.buddyList.get(j); 
    427                                 my_acc_cfg.buddyCfgs.add(bud.cfg); 
    428                         } 
    429                          
    430                         accCfgs.add(my_acc_cfg); 
    431                 } 
    432         } 
    433          
    434         private void saveConfig(String filename) { 
    435                 JsonDocument json = new JsonDocument(); 
    436                  
    437                 try { 
    438                         /* Write endpoint config */ 
    439                         json.writeObject(epConfig); 
    440                          
    441                         /* Write transport config */ 
    442                         ContainerNode tp_node = json.writeNewContainer("SipTransport"); 
    443                         sipTpConfig.writeObject(tp_node); 
    444                          
    445                         /* Write account configs */ 
    446                         buildAccConfigs(); 
    447                         ContainerNode accs_node = json.writeNewArray("accounts"); 
    448                         for (int i = 0; i < accCfgs.size(); i++) { 
    449                                 accCfgs.get(i).writeObject(accs_node); 
    450                         } 
    451                          
    452                         /* Save file */ 
    453                         json.saveFile(filename); 
    454                 } catch (Exception e) {} 
    455  
    456                 /* Force delete json now, as I found that Java somehow destroys it 
    457                  * after lib has been destroyed and from non-registered thread. 
    458                  */ 
    459                 json.delete(); 
    460         } 
    461          
    462         public void deinit() { 
    463                 String configPath = appDir + "/" + configName; 
    464                 saveConfig(configPath); 
    465                  
    466                 /* Try force GC to avoid late destroy of PJ objects as they should be 
    467                  * deleted before lib is destroyed. 
    468                  */ 
    469                 Runtime.getRuntime().gc(); 
    470                  
    471                 /* Shutdown pjsua. Note that Endpoint destructor will also invoke 
    472                  * libDestroy(), so this will be a test of double libDestroy(). 
    473                  */ 
    474                 try { 
    475                         ep.libDestroy(); 
    476                 } catch (Exception e) {} 
    477                  
    478                 /* Force delete Endpoint here, to avoid deletion from a non- 
    479                  * registered thread (by GC?).  
    480                  */ 
    481                 ep.delete(); 
    482                 ep = null; 
    483         }  
    484 } 
     281    static { 
     282        try{ 
     283            System.loadLibrary("openh264"); 
     284            System.loadLibrary("yuv"); 
     285        } catch (UnsatisfiedLinkError e) { 
     286            System.out.println("UnsatisfiedLinkError: " + e.getMessage()); 
     287            System.out.println("This could be safely ignored if you " + 
     288                               "don't need video."); 
     289        } 
     290        System.loadLibrary("pjsua2"); 
     291        System.out.println("Library loaded"); 
     292    } 
     293 
     294    public static Endpoint ep = new Endpoint(); 
     295    public static MyAppObserver observer; 
     296    public ArrayList<MyAccount> accList = new ArrayList<MyAccount>(); 
     297 
     298    private ArrayList<MyAccountConfig> accCfgs = 
     299                                          new ArrayList<MyAccountConfig>(); 
     300    private EpConfig epConfig = new EpConfig(); 
     301    private TransportConfig sipTpConfig = new TransportConfig(); 
     302    private String appDir; 
     303 
     304    /* Maintain reference to log writer to avoid premature cleanup by GC */ 
     305    private MyLogWriter logWriter; 
     306 
     307    private final String configName = "pjsua2.json"; 
     308    private final int SIP_PORT  = 6000; 
     309    private final int LOG_LEVEL = 4; 
     310 
     311    public void init(MyAppObserver obs, String app_dir) 
     312    { 
     313        init(obs, app_dir, false); 
     314    } 
     315 
     316    public void init(MyAppObserver obs, String app_dir, 
     317                     boolean own_worker_thread) 
     318    { 
     319        observer = obs; 
     320        appDir = app_dir; 
     321 
     322        /* Create endpoint */ 
     323        try { 
     324            ep.libCreate(); 
     325        } catch (Exception e) { 
     326            return; 
     327        } 
     328 
     329 
     330        /* Load config */ 
     331        String configPath = appDir + "/" + configName; 
     332        File f = new File(configPath); 
     333        if (f.exists()) { 
     334            loadConfig(configPath); 
     335        } else { 
     336            /* Set 'default' values */ 
     337            sipTpConfig.setPort(SIP_PORT); 
     338        } 
     339 
     340        /* Override log level setting */ 
     341        epConfig.getLogConfig().setLevel(LOG_LEVEL); 
     342        epConfig.getLogConfig().setConsoleLevel(LOG_LEVEL); 
     343 
     344        /* Set log config. */ 
     345        LogConfig log_cfg = epConfig.getLogConfig(); 
     346        logWriter = new MyLogWriter(); 
     347        log_cfg.setWriter(logWriter); 
     348        log_cfg.setDecor(log_cfg.getDecor() &  
     349                         ~(pj_log_decoration.PJ_LOG_HAS_CR.swigValue() |  
     350                         pj_log_decoration.PJ_LOG_HAS_NEWLINE.swigValue())); 
     351 
     352        /* Set ua config. */ 
     353        UaConfig ua_cfg = epConfig.getUaConfig(); 
     354        ua_cfg.setUserAgent("Pjsua2 Android " + ep.libVersion().getFull()); 
     355        StringVector stun_servers = new StringVector(); 
     356        stun_servers.add("stun.pjsip.org"); 
     357        ua_cfg.setStunServer(stun_servers); 
     358        if (own_worker_thread) { 
     359            ua_cfg.setThreadCnt(0); 
     360            ua_cfg.setMainThreadOnly(true); 
     361        } 
     362 
     363        /* Init endpoint */ 
     364        try { 
     365            ep.libInit(epConfig); 
     366        } catch (Exception e) { 
     367            return; 
     368        } 
     369 
     370        /* Create transports. */ 
     371        try { 
     372            ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP, 
     373                               sipTpConfig); 
     374        } catch (Exception e) { 
     375            System.out.println(e); 
     376        } 
     377 
     378        try { 
     379            ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP, 
     380                               sipTpConfig); 
     381        } catch (Exception e) { 
     382            System.out.println(e); 
     383        } 
     384 
     385        /* Create accounts. */ 
     386        for (int i = 0; i < accCfgs.size(); i++) { 
     387            MyAccountConfig my_cfg = accCfgs.get(i); 
     388            MyAccount acc = addAcc(my_cfg.accCfg); 
     389            if (acc == null) 
     390                continue; 
     391 
     392            /* Add Buddies */ 
     393            for (int j = 0; j < my_cfg.buddyCfgs.size(); j++) { 
     394                BuddyConfig bud_cfg = my_cfg.buddyCfgs.get(j); 
     395                acc.addBuddy(bud_cfg); 
     396            } 
     397        } 
     398 
     399        /* Start. */ 
     400        try { 
     401            ep.libStart(); 
     402        } catch (Exception e) { 
     403            return; 
     404        } 
     405    } 
     406 
     407    public MyAccount addAcc(AccountConfig cfg) 
     408    { 
     409        MyAccount acc = new MyAccount(cfg); 
     410        try { 
     411            acc.create(cfg); 
     412        } catch (Exception e) { 
     413            acc = null; 
     414            return null; 
     415        } 
     416 
     417        accList.add(acc); 
     418        return acc; 
     419    } 
     420 
     421    public void delAcc(MyAccount acc) 
     422    { 
     423        accList.remove(acc); 
     424    } 
     425 
     426    private void loadConfig(String filename) 
     427    { 
     428        JsonDocument json = new JsonDocument(); 
     429 
     430        try { 
     431            /* Load file */ 
     432            json.loadFile(filename); 
     433            ContainerNode root = json.getRootContainer(); 
     434 
     435            /* Read endpoint config */ 
     436            epConfig.readObject(root); 
     437 
     438            /* Read transport config */ 
     439            ContainerNode tp_node = root.readContainer("SipTransport"); 
     440            sipTpConfig.readObject(tp_node); 
     441 
     442            /* Read account configs */ 
     443            accCfgs.clear(); 
     444            ContainerNode accs_node = root.readArray("accounts"); 
     445            while (accs_node.hasUnread()) { 
     446                MyAccountConfig acc_cfg = new MyAccountConfig(); 
     447                acc_cfg.readObject(accs_node); 
     448                accCfgs.add(acc_cfg); 
     449            } 
     450        } catch (Exception e) { 
     451            System.out.println(e); 
     452        } 
     453 
     454        /* Force delete json now, as I found that Java somehow destroys it 
     455        * after lib has been destroyed and from non-registered thread. 
     456        */ 
     457        json.delete(); 
     458    } 
     459 
     460    private void buildAccConfigs() 
     461    { 
     462        /* Sync accCfgs from accList */ 
     463        accCfgs.clear(); 
     464        for (int i = 0; i < accList.size(); i++) { 
     465            MyAccount acc = accList.get(i); 
     466            MyAccountConfig my_acc_cfg = new MyAccountConfig(); 
     467            my_acc_cfg.accCfg = acc.cfg; 
     468 
     469            my_acc_cfg.buddyCfgs.clear(); 
     470            for (int j = 0; j < acc.buddyList.size(); j++) { 
     471                MyBuddy bud = acc.buddyList.get(j); 
     472                my_acc_cfg.buddyCfgs.add(bud.cfg); 
     473            } 
     474 
     475            accCfgs.add(my_acc_cfg); 
     476        } 
     477    } 
     478 
     479    private void saveConfig(String filename) 
     480    { 
     481        JsonDocument json = new JsonDocument(); 
     482 
     483        try { 
     484            /* Write endpoint config */ 
     485            json.writeObject(epConfig); 
     486 
     487            /* Write transport config */ 
     488            ContainerNode tp_node = json.writeNewContainer("SipTransport"); 
     489            sipTpConfig.writeObject(tp_node); 
     490 
     491            /* Write account configs */ 
     492            buildAccConfigs(); 
     493            ContainerNode accs_node = json.writeNewArray("accounts"); 
     494            for (int i = 0; i < accCfgs.size(); i++) { 
     495                accCfgs.get(i).writeObject(accs_node); 
     496            } 
     497 
     498            /* Save file */ 
     499            json.saveFile(filename); 
     500        } catch (Exception e) {} 
     501 
     502        /* Force delete json now, as I found that Java somehow destroys it 
     503        * after lib has been destroyed and from non-registered thread. 
     504        */ 
     505        json.delete(); 
     506    } 
     507 
     508    public void deinit() 
     509    { 
     510        String configPath = appDir + "/" + configName; 
     511        saveConfig(configPath); 
     512 
     513        /* Try force GC to avoid late destroy of PJ objects as they should be 
     514        * deleted before lib is destroyed. 
     515        */ 
     516        Runtime.getRuntime().gc(); 
     517 
     518        /* Shutdown pjsua. Note that Endpoint destructor will also invoke 
     519        * libDestroy(), so this will be a test of double libDestroy(). 
     520        */ 
     521        try { 
     522            ep.libDestroy(); 
     523        } catch (Exception e) {} 
     524 
     525        /* Force delete Endpoint here, to avoid deletion from a non- 
     526        * registered thread (by GC?).  
     527        */ 
     528        ep.delete(); 
     529        ep = null; 
     530    }  
     531} 
Note: See TracChangeset for help on using the changeset viewer.