Changeset 4292


Ignore:
Timestamp:
Nov 1, 2012 6:14:15 AM (8 years ago)
Author:
nanang
Message:

Re #1546: apjloader updates: handle activity destroy-recreate, e.g: on orientation change or device sleep, and minors (cleaner activity handler, copy log to logcat, etc).

Location:
pjproject/branches/projects/android/pjsip-apps/src/apjloader
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/android/pjsip-apps/src/apjloader/AndroidManifest.xml

    r4289 r4292  
    77        android:minSdkVersion="15" 
    88        android:targetSdkVersion="15" /> 
    9      
     9 
    1010    <uses-permission android:name="android.permission.INTERNET" /> 
    1111    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
     
    1616    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    1717    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    18     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 
    19     <uses-permission android:name="android.permission.READ_CONTACTS" /> 
    20     <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 
    21     <uses-permission android:name="android.permission.CALL_PHONE" /> 
    2218    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    23     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 
    2419    <uses-permission android:name="android.permission.VIBRATE" /> 
    25     <uses-permission android:name="android.permission.BLUETOOTH" /> 
    2620    <uses-permission android:name="android.permission.READ_LOGS" /> 
    2721    <uses-permission android:name="android.permission.USE_SIP" /> 
    2822    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    2923    <uses-permission android:name="android.permission.CAMERA" /> 
    30     <uses-permission android:name="android.permission.BROADCAST_STICKY" /> 
    31     <uses-permission android:name="android.permission.READ_PROFILE" /> 
    32   
    33     <uses-feature android:name="android.hardware.sip.voip" android:required="true" /> 
    34     <uses-feature android:name="android.hardware.microphone" android:required="true" /> 
    35      
     24 
     25    <uses-feature 
     26        android:name="android.hardware.microphone" 
     27        android:required="true" /> 
     28 
    3629    <application 
    3730        android:icon="@drawable/ic_launcher" 
     
    3932        android:theme="@android:style/Theme.DeviceDefault.NoActionBar" > 
    4033        <activity 
    41             android:screenOrientation="portrait" 
    42             android:configChanges="keyboardHidden|orientation|screenLayout" 
    4334            android:name=".MainActivity" 
     35            android:windowSoftInputMode="stateHidden" 
    4436            android:label="@string/title_activity_main" > 
    4537            <intent-filter> 
  • pjproject/branches/projects/android/pjsip-apps/src/apjloader/src/org/pjsip/apjloader/MainActivity.java

    r4289 r4292  
    22 
    33package org.pjsip.apjloader; 
     4 
     5import java.lang.ref.WeakReference; 
    46 
    57import android.app.Activity; 
     
    1012import android.os.Message; 
    1113import android.text.method.ScrollingMovementMethod; 
     14import android.util.Log; 
    1215import android.view.KeyEvent; 
    1316import android.view.View; 
     
    2225        public static final String TAG = "apjloader"; 
    2326        public static final String NEWLINE = "\r\n"; 
    24         public static final Boolean AUTOKILL_ON_FINISHED = true; 
     27        public static final Boolean AUTOKILL_ON_FINISH = false; 
     28        public static final int MAX_LOG_CHARS = 20000; // set to zero to disable limit 
    2529        public enum MSG_TYPE { 
    2630                STR_INFO, 
     
    4246 
    4347class LoaderThread extends Thread { 
    44         private Handler ui_handler; 
     48        private WeakReference<Handler> ui_handler; 
    4549 
    4650        public LoaderThread(Handler ui_handler_) { 
    47                 ui_handler = ui_handler_; 
     51                set_ui_handler(ui_handler_); 
     52        } 
     53         
     54        public void set_ui_handler(Handler ui_handler_) { 
     55                ui_handler = new WeakReference<Handler>(ui_handler_); 
    4856        } 
    4957         
     
    5664                                                 "--clock-rate=8000", 
    5765                                                 "--auto-answer=200", 
    58                                                 }; 
    59                  
    60                 LOG.INFO(ui_handler, "Starting module.." + CONST.NEWLINE); 
     66                                                 }; 
     67                 
     68                Handler ui = ui_handler.get(); 
     69                LOG.INFO(ui, "Starting module.." + CONST.NEWLINE); 
    6170                int rc = apjloader.main(argv.length, argv); 
    62                 LOG.INFO(ui_handler, "Module finished with return code: " +  
     71                 
     72                ui = ui_handler.get(); 
     73                LOG.INFO(ui, "Module finished with return code: " +  
    6374                                 Integer.toString(rc) + CONST.NEWLINE); 
    6475                 
    6576                apjloader.destroy_stdio_pipe(); 
    6677 
    67                 if (CONST.AUTOKILL_ON_FINISHED) { 
    68                         Message msg = Message.obtain(ui_handler, CONST.MSG_TYPE.QUIT.ordinal()); 
    69                         ui_handler.sendMessageDelayed(msg, 2000); 
     78                if (CONST.AUTOKILL_ON_FINISH) { 
     79                        ui = ui_handler.get(); 
     80                        Message msg = Message.obtain(ui, CONST.MSG_TYPE.QUIT.ordinal()); 
     81                        ui.sendMessageDelayed(msg, 2000); 
    7082                } 
    7183        } 
     
    7385 
    7486class OutputThread extends Thread { 
    75         private Handler ui_handler; 
     87        private WeakReference<Handler> ui_handler; 
    7688         
    7789        public OutputThread(Handler ui_handler_) { 
    78                 ui_handler  = ui_handler_; 
     90                set_ui_handler(ui_handler_); 
     91        } 
     92         
     93        public void set_ui_handler(Handler ui_handler_) { 
     94                ui_handler = new WeakReference<Handler>(ui_handler_); 
    7995        } 
    8096         
     
    87103                        byte ch[] = new byte[1]; 
    88104                        int rc = apjloader.read_from_stdout(ch); 
     105                        Handler ui = ui_handler.get(); 
    89106                         
    90107                        if (rc == 0) { 
    91108                                if (ch[0]=='\r' || ch[0]== '\n') { 
    92109                                        if (sb.length() > 0) { 
    93                                                 LOG.INFO(ui_handler, sb.toString()+CONST.NEWLINE); 
     110                                                LOG.INFO(ui, sb.toString()+CONST.NEWLINE); 
    94111                                                sb.delete(0, sb.length()); 
    95112                                        } 
     
    98115                                }                                        
    99116                        } else { 
    100                                 LOG.INFO(ui_handler, "Stdout pipe stopped, rc="+Integer.toString(rc)+CONST.NEWLINE); 
     117                                LOG.INFO(ui, "Stdout pipe stopped, rc="+Integer.toString(rc)+CONST.NEWLINE); 
    101118                                break; 
    102119                        } 
     
    109126        private TextView log_view; 
    110127        private ScrollView log_scroll_view; 
    111         EditText input_cmd; 
    112  
    113         /** Called when the activity is first created. */ 
    114     @Override 
    115     public void onCreate(Bundle savedInstanceState) { 
    116         super.onCreate(savedInstanceState); 
    117         setContentView(R.layout.activity_main); 
    118  
    119         init_view(); 
    120          
    121         print_log("Loading module.." + CONST.NEWLINE); 
    122         int rc = init_lib(); 
    123         if (rc != 0) 
     128        private EditText input_cmd; 
     129        private MyHandler ui_handler = new MyHandler(this); 
     130        private static OutputThread ot; 
     131        private static LoaderThread lt; 
     132         
     133        private static class MyHandler extends Handler { 
     134                private final WeakReference<MainActivity> mTarget; 
     135                 
     136                public MyHandler(MainActivity target) { 
     137                        mTarget = new WeakReference<MainActivity>(target);  
     138                } 
     139                 
     140                @Override 
     141                public void handleMessage(Message m) { 
     142                        MainActivity target = mTarget.get(); 
     143                        if (target == null) 
     144                                return; 
     145                         
     146                        if (m.what == CONST.MSG_TYPE.STR_INFO.ordinal() || 
     147                                m.what == CONST.MSG_TYPE.STR_ERROR.ordinal()) 
     148                        { 
     149                                target.print_log((String)m.obj); 
     150                        } else if (m.what == CONST.MSG_TYPE.QUIT.ordinal()) { 
     151                                target.finish(); 
     152                                System.gc(); 
     153                                android.os.Process.killProcess(android.os.Process.myPid()); 
     154                        } 
     155                } 
     156    } 
     157     
     158    @Override 
     159    protected void onCreate(Bundle savedInstanceState) { 
     160        Log.d(CONST.TAG, "=== Activity::onCreate() ==="); 
     161        super.onCreate(savedInstanceState); 
     162         
     163        init_view(); 
     164 
     165        int rc = init_lib(); 
     166        if (rc != 0) { 
    124167                print_log("Failed loading module: " + Integer.toString(rc) + CONST.NEWLINE); 
    125         } 
    126  
     168                return; 
     169        } 
     170 
     171        ot.set_ui_handler(ui_handler); 
     172        lt.set_ui_handler(ui_handler); 
     173        } 
     174 
     175    @Override 
     176    protected void onStart() { 
     177        Log.d(CONST.TAG, "=== Activity::onStart() ==="); 
     178        super.onStart(); 
     179    } 
     180     
     181    @Override 
     182    protected void onRestart() { 
     183        Log.d(CONST.TAG, "=== Activity::onRestart() ==="); 
     184        super.onRestart(); 
     185    } 
     186 
     187    @Override 
     188    protected void onResume() { 
     189        Log.d(CONST.TAG, "=== Activity::onResume() ==="); 
     190        super.onResume(); 
     191    } 
     192 
     193    @Override 
     194    protected void onPause() { 
     195        Log.d(CONST.TAG, "=== Activity::onPause() ==="); 
     196        super.onPause(); 
     197    } 
     198 
     199    @Override 
     200    protected void onStop() { 
     201        Log.d(CONST.TAG, "=== Activity::onStop() ==="); 
     202        super.onStop(); 
     203    } 
     204 
     205    @Override 
     206    protected void onDestroy() { 
     207        Log.d(CONST.TAG, "=== Activity::onDestroy() ==="); 
     208        super.onDestroy(); 
     209    } 
     210     
     211    @Override 
     212    protected void onSaveInstanceState(Bundle outState) { 
     213                super.onSaveInstanceState(outState); 
     214                outState.putString("INPUT_CMD", input_cmd.getText().toString()); 
     215                outState.putString("LOG_VIEW", log_view.getText().toString()); 
     216    } 
     217 
     218    @Override 
     219    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     220                super.onRestoreInstanceState(savedInstanceState); 
     221                input_cmd.setText(savedInstanceState.getString("INPUT_CMD")); 
     222                log_view.setText(savedInstanceState.getString("LOG_VIEW")); 
     223        log_view.post(new Runnable() { 
     224            public void run() { 
     225                log_scroll_view.fullScroll(View.FOCUS_DOWN); 
     226            } 
     227        });      
     228    } 
     229     
     230           
    127231    private View.OnClickListener on_send_cmd_click = new View.OnClickListener() { 
    128232        public void onClick(View v) { 
     
    161265    private void print_log(String st) { 
    162266        log_view.append(st); 
    163         //Log.i(CONST.TAG, st); 
    164  
     267        Log.d(CONST.TAG, st); 
     268         
     269        // Limit log view text length 
     270        if (CONST.MAX_LOG_CHARS > 0 && log_view.length() > CONST.MAX_LOG_CHARS) { 
     271                int to_del = log_view.length() - CONST.MAX_LOG_CHARS + 100; 
     272                if (to_del > log_view.length()) 
     273                        to_del = log_view.length(); 
     274                log_view.getEditableText().delete(0, to_del); 
     275        } 
     276 
     277        // Scroll to bottom 
    165278        log_view.post(new Runnable() { 
    166279            public void run() { 
     
    170283    } 
    171284     
    172     private Handler ui_handler = new Handler() { 
    173                 @Override 
    174                 public void handleMessage(Message m) { 
    175                         if (m.what == CONST.MSG_TYPE.STR_INFO.ordinal() || 
    176                                 m.what == CONST.MSG_TYPE.STR_ERROR.ordinal()) 
    177                         { 
    178                                 print_log((String)m.obj); 
    179                         } else if (m.what == CONST.MSG_TYPE.QUIT.ordinal()) { 
    180                                 finish(); 
    181                                 System.gc(); 
    182                                 android.os.Process.killProcess(android.os.Process.myPid()); 
    183                         } 
    184                 } 
    185     }; 
    186  
    187285    private void hide_soft_keyboard() { 
    188286        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     
    191289     
    192290        private void init_view() { 
    193         Button send_cmd_button = (Button)findViewById(R.id.send_cmd_button); 
     291        setContentView(R.layout.activity_main); 
     292 
     293        Button send_cmd_button = (Button)findViewById(R.id.send_cmd_button); 
    194294        send_cmd_button.setOnClickListener(on_send_cmd_click); 
    195295 
     
    199299        input_cmd = (EditText)findViewById(R.id.input_cmd); 
    200300        input_cmd.setOnKeyListener(on_input_cmd_key); 
    201          
     301 
    202302        log_view = (TextView)findViewById(R.id.output); 
    203303        log_view.setMovementMethod(new ScrollingMovementMethod()); 
    204         log_view.setText(""); 
    205304         
    206305        log_scroll_view = (ScrollView)findViewById(R.id.output_scroller); 
    207306        } 
    208307         
    209         private int init_stdio_pipes() { 
    210                 int rc = apjloader.init_stdio_pipe(); 
    211                 if (rc != 0) 
    212                         return rc; 
    213                  
    214                 return 0; 
    215         } 
    216          
    217308        private int init_lib() { 
     309                if (ot != null || lt != null) 
     310                        return 0; 
     311                 
     312        print_log("Loading module.." + CONST.NEWLINE); 
     313         
    218314                try { 
    219315                        System.loadLibrary(CONST.LIB_FILENAME); 
     
    232328                } 
    233329                 
    234         int rc = init_stdio_pipes(); 
     330                int rc = apjloader.init_stdio_pipe(); 
    235331        print_log("Stdio pipes inited: " + Integer.toString(rc) + CONST.NEWLINE); 
    236332         
    237         OutputThread ot = new OutputThread(ui_handler); 
     333        ot = new OutputThread(ui_handler); 
    238334                ot.start(); 
    239335                 
    240         LoaderThread lt = new LoaderThread(ui_handler); 
     336        lt = new LoaderThread(ui_handler); 
    241337        lt.start(); 
    242338         
Note: See TracChangeset for help on using the changeset viewer.