• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * MainActivity.java - libwebsockets test service for Android
3  *
4  * Copyright (C) 2016 Alexander Bruines <alexander.bruines@gmail.com>
5  *
6  * This file is made available under the Creative Commons CC0 1.0
7  * Universal Public Domain Dedication.
8  *
9  * The person who associated a work with this deed has dedicated
10  * the work to the public domain by waiving all of his or her rights
11  * to the work worldwide under copyright law, including all related
12  * and neighboring rights, to the extent allowed by law. You can copy,
13  * modify, distribute and perform the work, even for commercial purposes,
14  * all without asking permission.
15  *
16  * The test apps are intended to be adapted for use in your code, which
17  * may be proprietary.  So unlike the library itself, they are licensed
18  * Public Domain.
19  */
20 
21 package org.libwebsockets.client;
22 
23 
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.content.Intent;
28 import android.content.ServiceConnection;
29 import android.os.IBinder;
30 import android.os.Message;
31 import android.os.Messenger;
32 import android.os.RemoteException;
33 import android.support.v7.app.AlertDialog;
34 import android.support.v7.app.AppCompatActivity;
35 import android.os.Bundle;
36 import android.util.Log;
37 import android.view.inputmethod.InputMethodManager;
38 import android.view.View;
39 import android.widget.EditText;
40 import android.widget.TextView;
41 
42 public class MainActivity extends AppCompatActivity implements LwsService.OutputInterface {
43 
44     /** This is the Messenger that handles output from the Service */
45     private Messenger mMessenger = null;
46 
47     /** The Messenger for sending commands to the Service  */
48     private Messenger mService = null;
49     private ServiceConnection mServiceConnection = null;
50 
51     private boolean mThreadIsRunning = false;
52     private boolean mThreadIsSuspended = false;
53 
54     private TextView tvCounter;
55     private EditText etServer;
56     private EditText etPort;
57 
58     @Override
onCreate(Bundle savedInstanceState)59     protected void onCreate(Bundle savedInstanceState) {
60         super.onCreate(savedInstanceState);
61         setContentView(R.layout.activity_main);
62 
63         // Get the layout items
64         tvCounter = (TextView) findViewById(R.id.textView_counter);
65         etServer = (EditText) findViewById(R.id.editText_serverLocation);
66         etPort = (EditText) findViewById(R.id.editText_portNumber);
67 
68         // Create the Messenger for handling output from the service
69         mMessenger = new Messenger(new LwsService.OutputHandler(this));
70 
71         // Restore state from the Bundle when restarting due to a device change.
72         if(savedInstanceState!=null) {
73             mThreadIsRunning = savedInstanceState.getBoolean("mThreadIsRunning");
74         }
75 
76         mServiceConnection = new ServiceConnection() {
77             @Override
78             public void onServiceConnected(ComponentName name, IBinder service) {
79                 mService = new Messenger(service);
80                 try {
81                     // Set the output messenger by starting the thread
82                     Message msg = Message.obtain(null, LwsService.MSG_SET_OUTPUT_HANDLER, 0, 0);
83                     msg.replyTo = mMessenger;
84                     mService.send(msg);
85                     if(mThreadIsRunning){
86                         // If the thread is already running at this point it means
87                         // that the application was restarted after a device change.
88                         // This implies that the thread was suspended by the onStop method.
89                         msg = Message.obtain(null, LwsService.MSG_THREAD_RESUME, 0, 0);
90                         mService.send(msg);
91                         mThreadIsSuspended = false;
92                     }
93                 }
94                 catch(RemoteException e) {
95                     e.printStackTrace();
96                 }
97             }
98 
99             @Override
100             public void onServiceDisconnected(ComponentName name) {
101                 Log.e("MainActivity","onServiceDisconnected !");
102                 mService = null;
103             }
104         };
105 
106         if(savedInstanceState==null){
107             startService(new Intent(getBaseContext(), LwsService.class));
108         }
109     }
110 
111     @Override
onSaveInstanceState(Bundle outState)112     protected void onSaveInstanceState(Bundle outState) {
113         super.onSaveInstanceState(outState);
114         outState.putBoolean("mThreadIsRunning", mThreadIsRunning);
115     }
116 
117     @Override
onStart()118     protected void onStart() {
119         super.onStart();
120         bindService(new Intent(getBaseContext(), LwsService.class), mServiceConnection, Context.BIND_AUTO_CREATE);
121     }
122 
123     @Override
onStop()124     protected void onStop() {
125         super.onStop();
126         if(mThreadIsRunning) {
127             if (!mThreadIsSuspended) {
128                 try {
129                     mService.send(Message.obtain(null, LwsService.MSG_THREAD_SUSPEND, 0, 0));
130                 } catch (RemoteException e) {
131                     e.printStackTrace();
132                 }
133                 mThreadIsSuspended = true;
134             }
135         }
136         unbindService(mServiceConnection);
137     }
138 
139     @Override
onDestroy()140     protected void onDestroy() {
141         super.onDestroy();
142         if(isFinishing()){
143             stopService(new Intent(getBaseContext(), LwsService.class));
144         }
145     }
146 
147     /** Implement the interface to receive output from the LwsService */
148     @Override
handleOutputMessage(Message message)149     public void handleOutputMessage(Message message) {
150         switch(message.what) {
151             case LwsService.MSG_DUMB_INCREMENT_PROTOCOL_COUNTER:
152                 tvCounter.setText((String)message.obj);
153                 break;
154             case LwsService.MSG_LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
155                 connectErrorListener();
156                 break;
157             case LwsService.MSG_LWS_CALLBACK_CLIENT_ESTABLISHED:
158                 break;
159             case LwsService.MSG_THREAD_STARTED:
160                 // The thread was started
161                 mThreadIsRunning = true;
162                 mThreadIsSuspended = false;
163                 break;
164             case LwsService.MSG_THREAD_STOPPED:
165                 // The thread was stopped
166                 mThreadIsRunning = false;
167                 mThreadIsSuspended = false;
168                 break;
169             case LwsService.MSG_THREAD_SUSPENDED:
170                 // The thread is suspended
171                 mThreadIsRunning = true;
172                 mThreadIsSuspended = true;
173                 break;
174             case LwsService.MSG_THREAD_RESUMED:
175                 // the thread was resumed
176                 mThreadIsRunning = true;
177                 mThreadIsSuspended = false;
178                 break;
179             default:
180                 break;
181         }
182     }
183 
connectErrorListener()184     private void connectErrorListener(){
185         try {
186             Message msg;
187             if(mThreadIsRunning) {
188                 msg = Message.obtain(null, LwsService.MSG_THREAD_STOP);
189                 mService.send(msg);
190             }
191             AlertDialog.Builder adb = new AlertDialog.Builder(this);
192             adb.setTitle("Error");
193             adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
194                 public void onClick(DialogInterface dialog, int which) {
195                 }
196             });
197             adb.setMessage("Could not connect to the server.");
198             adb.show();
199         }
200         catch (RemoteException e){}
201     }
202 
203     /**
204      * Start/Stop Button Handler
205      */
206 
clickStart(View v)207     public void clickStart(View v) {
208         if(!mThreadIsRunning) {
209             View view = this.getCurrentFocus();
210             if (view != null) {
211                 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
212                 imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
213             }
214             mThreadIsRunning = true;
215             mThreadIsSuspended = false;
216             try {
217                 Message msg = Message.obtain(null, LwsService.MSG_SET_CONNECTION_PARAMETERS, 0, 0);
218                 int port = 0;
219                 if(!etPort.getText().toString().equals("")) // prevent NumberformatException
220                     port = Integer.parseInt(etPort.getText().toString());
221                 LwsService.ConnectionParameters parameters = new LwsService.ConnectionParameters(
222                         etServer.getText().toString(),
223                         port
224                 );
225                 msg.obj = parameters;
226                 mService.send(msg);
227                 msg = Message.obtain(null, LwsService.MSG_THREAD_START, 0, 0);
228                 mService.send(msg);
229             }
230             catch(RemoteException e) {
231                 e.printStackTrace();
232             }
233         }
234         else {
235             try {
236                 mService.send(Message.obtain(null, LwsService.MSG_THREAD_STOP, 0, 0));
237             }
238             catch(RemoteException e) {
239                 e.printStackTrace();
240             }
241             mThreadIsRunning = false;
242             mThreadIsSuspended = false;
243         }
244     }
245 
246 }
247