Merge branch 'master' into simulator
[platform/upstream/iotivity.git] / service / resource-encapsulation / examples / android / RESampleClientApp / app / src / main / java / org / iotivity / service / sample / client / ResourceClientActivity.java
1 /******************************************************************
2  * Copyright 2015 Samsung Electronics All Rights Reserved.
3  * <p>
4  * <p>
5  * <p>
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  * <p>
10  * http://www.apache.org/licenses/LICENSE-2.0
11  * <p>
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  ******************************************************************/
18 package org.iotivity.service.sample.client;
19
20 import static org.iotivity.service.client.RcsRemoteResourceObject.OnCacheUpdatedListener;
21 import static org.iotivity.service.client.RcsRemoteResourceObject.OnStateChangedListener;
22 import static org.iotivity.service.client.RcsRemoteResourceObject.ResourceState;
23
24 import java.lang.ref.WeakReference;
25
26 import org.iotivity.service.RcsException;
27 import org.iotivity.service.RcsResourceAttributes;
28 import org.iotivity.service.RcsValue;
29 import org.iotivity.service.client.RcsAddress;
30 import org.iotivity.service.client.RcsDiscoveryManager;
31 import org.iotivity.service.client.RcsDiscoveryManager.OnResourceDiscoveredListener;
32 import org.iotivity.service.client.RcsRemoteResourceObject;
33 import org.iotivity.service.client.RcsRemoteResourceObject.OnRemoteAttributesReceivedListener;
34
35 import android.app.Activity;
36 import android.app.AlertDialog;
37 import android.content.DialogInterface;
38 import android.os.Bundle;
39 import android.os.Handler;
40 import android.os.Message;
41 import android.util.Log;
42 import android.view.View;
43 import android.widget.AdapterView;
44 import android.widget.AdapterView.OnItemClickListener;
45 import android.widget.ArrayAdapter;
46 import android.widget.Button;
47 import android.widget.EditText;
48 import android.widget.ListView;
49 import android.widget.TextView;
50 import android.widget.Toast;
51
52 /*
53  * Activity for handling user's selection on UI for Resource Client APIs.
54  * & for updating UI.
55  */
56 public class ResourceClientActivity extends Activity
57         implements OnItemClickListener {
58
59     private static final String LOG_TAG = ResourceClientActivity.class
60             .getSimpleName();
61
62     private static final int MSG_ID_RESOURCE_DISCOVERED = 0;
63     private static final int MSG_ID_ATTRIBUTE_RECEIVED  = 1;
64     private static final int MSG_ID_PRINT_LOG           = 2;
65
66     private static final String ATTR_KEY_TEMPERATURE = "Temperature";
67
68     private TextView mLogView;
69     private ListView mListView;
70     private Button   mDiscoveryBtn;
71
72     private Handler            mHandler;
73     private ArrayAdapter<Item> mItemAdapter;
74
75     private RcsDiscoveryManager.DiscoveryTask mDiscoveryTask;
76     private RcsRemoteResourceObject           mResourceObj;
77
78     private OnResourceDiscoveredListener mOnResourceDiscoveredListener = new OnResourceDiscoveredListener() {
79
80         @Override
81         public void onResourceDiscovered(
82                 RcsRemoteResourceObject foundResource) {
83             Log.i(LOG_TAG, "onResourceDiscovered");
84
85             mHandler.obtainMessage(MSG_ID_RESOURCE_DISCOVERED, foundResource)
86                     .sendToTarget();
87         }
88     };
89
90     private OnStateChangedListener mOnStateChangedListener = new OnStateChangedListener() {
91
92         @Override
93         public void onStateChanged(ResourceState resourceState) {
94             Log.i(LOG_TAG, "onStateChanged");
95
96             mHandler.obtainMessage(MSG_ID_PRINT_LOG,
97                     "Current Resource State : " + resourceState);
98         }
99     };
100
101     private OnRemoteAttributesReceivedListener mOnRemoteAttributesReceivedListener = new OnRemoteAttributesReceivedListener() {
102         @Override
103         public void onAttributesReceived(RcsResourceAttributes attrs,
104                 int eCode) {
105             Log.i(LOG_TAG, "onAttributesReceived");
106
107             mHandler.obtainMessage(MSG_ID_ATTRIBUTE_RECEIVED, attrs)
108                     .sendToTarget();
109         }
110     };
111
112     private OnCacheUpdatedListener mOnCacheUpdatedListener = new OnCacheUpdatedListener() {
113         @Override
114         public void onCacheUpdated(RcsResourceAttributes attrs) {
115             Log.i(LOG_TAG, "onCacheUpdated");
116
117             mHandler.obtainMessage(MSG_ID_ATTRIBUTE_RECEIVED, attrs)
118                     .sendToTarget();
119         }
120     };
121
122     private Item mStartMonitoring = new Item("1. Start Monitoring") {
123         @Override
124         public void execute() throws RcsException {
125             if (mResourceObj.isMonitoring()) {
126                 printLog("Monitoring already started");
127                 return;
128             }
129
130             mResourceObj.startMonitoring(mOnStateChangedListener);
131         }
132     };
133
134     private Item mStopMonitoring = new Item("2. Stop Monitoring") {
135         @Override
136         public void execute() throws RcsException {
137             if (mResourceObj.isMonitoring()) {
138                 mResourceObj.stopMonitoring();
139                 printLog("Stopped Resource Monitoring");
140             } else {
141                 printLog("Monitoring not started");
142             }
143         }
144     };
145
146     private Item mGetRemoteAttributes = new Item("3. Get Remote Attributes") {
147         @Override
148         public void execute() throws RcsException {
149             mResourceObj
150                     .getRemoteAttributes(mOnRemoteAttributesReceivedListener);
151         }
152     };
153
154     private Item mSetRemoteAttributes = new Item("4. Set Remote Attributes") {
155
156         @Override
157         public void execute() throws RcsException {
158             showInputValueDialog();
159         }
160     };
161
162     private Item mStartCaching = new Item("5. Start Caching") {
163         @Override
164         public void execute() throws RcsException {
165             if (mResourceObj.isCaching()) {
166                 printLog("Caching already started");
167                 return;
168             }
169
170             mResourceObj.startCaching(mOnCacheUpdatedListener);
171         }
172     };
173
174     private Item mGetCacheState = new Item("6. Get Cache State") {
175         @Override
176         public void execute() throws RcsException {
177             printLog("Cache State : " + mResourceObj.getCacheState());
178         }
179     };
180
181     private Item mGetCachedAttributes = new Item(
182             "7. Get All Cached Attributes") {
183         @Override
184         public void execute() throws RcsException {
185             printAttributes(mResourceObj.getCachedAttributes());
186         }
187     };
188
189     private Item mGetCachedAttribute = new Item("8. Get Cached Attribute") {
190         @Override
191         public void execute() throws RcsException {
192             printLog(ATTR_KEY_TEMPERATURE + " : " + mResourceObj
193                     .getCachedAttribute(ATTR_KEY_TEMPERATURE).asInt());
194         }
195     };
196
197     private Item mStopCaching = new Item("9. Stop Caching") {
198         @Override
199         public void execute() throws RcsException {
200             mResourceObj.stopCaching();
201         }
202     };
203
204     @Override
205     protected void onCreate(Bundle savedInstanceState) {
206         super.onCreate(savedInstanceState);
207         setContentView(R.layout.activity_resource_client);
208
209         mListView = (ListView) findViewById(R.id.list_menu);
210         mLogView = (TextView) findViewById(R.id.text_log);
211         mDiscoveryBtn = (Button) findViewById(R.id.btn_discovery);
212
213         mHandler = new ClientHandler(this);
214
215         initMenuList();
216     }
217
218     @Override
219     protected void onDestroy() {
220         super.onDestroy();
221
222         if (mDiscoveryTask != null)
223             mDiscoveryTask.cancel();
224         if (mResourceObj != null)
225             mResourceObj.destroy();
226     }
227
228     private void initMenuList() {
229         Item[] items = new Item[] { mStartMonitoring, mStopMonitoring,
230                 mGetRemoteAttributes, mSetRemoteAttributes, mStartCaching,
231                 mGetCacheState, mGetCachedAttributes, mGetCachedAttribute,
232                 mStopCaching };
233
234         mItemAdapter = new ArrayAdapter<>(this,
235                 android.R.layout.simple_list_item_1, items);
236
237         mListView.setAdapter(mItemAdapter);
238
239         mListView.setOnItemClickListener(this);
240     }
241
242     @Override
243     public void onItemClick(AdapterView<?> parent, View view, int position,
244             long id) {
245         if (mResourceObj == null) {
246             showError("no discovered RemoteResourceObject");
247             return;
248         }
249
250         try {
251             mItemAdapter.getItem(position).execute();
252         } catch (RcsException e) {
253             showError(e);
254         }
255     }
256
257     public void onDiscoverResourceClick(View v) {
258         toggleDiscovery();
259     }
260
261     private void toggleDiscovery() {
262         if (mDiscoveryTask == null) {
263             try {
264                 mDiscoveryTask = RcsDiscoveryManager.getInstance()
265                         .discoverResource(RcsAddress.multicast(),
266                                 mOnResourceDiscoveredListener);
267                 mDiscoveryBtn.setText(R.string.cancel_discovery);
268
269                 mListView.setVisibility(View.INVISIBLE);
270
271                 if (mResourceObj != null) {
272                     mResourceObj.destroy();
273                     mResourceObj = null;
274                 }
275             } catch (RcsException e) {
276                 showError(e);
277             }
278         } else {
279             mDiscoveryTask.cancel();
280             mDiscoveryTask = null;
281
282             mDiscoveryBtn.setText(R.string.discover_resource);
283         }
284     }
285
286     private void printAttributes(RcsResourceAttributes attributes) {
287         try {
288             StringBuilder sb = new StringBuilder();
289             for (String key : attributes.keySet()) {
290                 sb.append(key + " : " + attributes.get(key));
291             }
292             printLog(sb.toString());
293         } catch (Exception e) {
294             printLog(e);
295         }
296     }
297
298     private void setRemoteResourceObject(
299             RcsRemoteResourceObject foundResource) {
300         if (mResourceObj != null) {
301             Log.w(LOG_TAG, "Another remote resource found...");
302             return;
303         }
304
305         mResourceObj = foundResource;
306
307         mListView.setVisibility(View.VISIBLE);
308         toggleDiscovery();
309
310         try {
311             printLog(resourceInfo(mResourceObj));
312         } catch (RcsException e) {
313             showError(e);
314         }
315     }
316
317     private void showInputValueDialog() {
318         final AlertDialog dialog = new AlertDialog.Builder(this)
319                 .setTitle("Enter the Temperature Value")
320                 .setView(R.layout.dialog_content_edit_text)
321                 .setNegativeButton("Cancel", null).create();
322
323         dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
324                 new DialogInterface.OnClickListener() {
325                     @Override
326                     public void onClick(DialogInterface dialogInterface,
327                             int which) {
328
329                         EditText temperatureValue = (EditText) dialog
330                                 .findViewById(R.id.attributeValue);
331
332                         try {
333                             RcsValue value = new RcsValue(Integer.parseInt(
334                                     temperatureValue.getText().toString()));
335
336                             RcsResourceAttributes attrs = new RcsResourceAttributes();
337                             attrs.put(ATTR_KEY_TEMPERATURE, value);
338
339                             mResourceObj.setRemoteAttributes(attrs,
340                                     mOnRemoteAttributesReceivedListener);
341                         } catch (NumberFormatException e) {
342                             showError("Please enter the Integer Value");
343                         } catch (RcsException e) {
344                             showError(e);
345                         }
346                     }
347                 });
348         dialog.show();
349     }
350
351     private void showError(String msg) {
352         Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
353         Log.e(LOG_TAG, msg);
354     }
355
356     private void showError(Exception e) {
357         Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
358         Log.e(LOG_TAG, e.getMessage(), e);
359     }
360
361     private void printLog(String message) {
362         Log.i(LOG_TAG, message);
363         mLogView.setText(message);
364     }
365
366     private void printLog(Exception e) {
367         Log.i(LOG_TAG, e.getMessage(), e);
368         mLogView.setText(e.getMessage());
369     }
370
371     private String resourceInfo(RcsRemoteResourceObject resourceObject)
372             throws RcsException {
373         StringBuilder sb = new StringBuilder();
374
375         sb.append("URI : " + resourceObject.getUri() + "\n");
376         sb.append("Host : " + resourceObject.getAddress() + "\n");
377         for (String type : resourceObject.getTypes()) {
378             sb.append("resourceType : " + type + "\n");
379         }
380
381         for (String itf : resourceObject.getInterfaces()) {
382             sb.append("resourceInterfaces : " + itf + "\n");
383         }
384
385         sb.append("isObservable : " + resourceObject.isObservable() + "\n");
386
387         return sb.toString();
388     }
389
390     private static abstract class Item {
391         private final String mTitle;
392
393         protected Item(String title) {
394             mTitle = title;
395         }
396
397         @Override
398         public String toString() {
399             return mTitle;
400         }
401
402         public abstract void execute() throws RcsException;
403     }
404
405     private static class ClientHandler extends Handler {
406         private WeakReference<ResourceClientActivity> mActivityRef;
407
408         private ClientHandler(ResourceClientActivity activity) {
409             mActivityRef = new WeakReference<>(activity);
410         }
411
412         @Override
413         public void handleMessage(Message msg) {
414             super.handleMessage(msg);
415
416             ResourceClientActivity activity = mActivityRef.get();
417             if (activity == null)
418                 return;
419
420             switch (msg.what) {
421                 case MSG_ID_RESOURCE_DISCOVERED:
422                     activity.setRemoteResourceObject(
423                             (RcsRemoteResourceObject) msg.obj);
424                     break;
425
426                 case MSG_ID_ATTRIBUTE_RECEIVED:
427                     activity.printAttributes((RcsResourceAttributes) msg.obj);
428                     break;
429
430                 case MSG_ID_PRINT_LOG:
431                     activity.printLog(msg.obj.toString());
432                     break;
433             }
434         }
435     }
436 }