370a53b45fca6139d36e4ea177dc0ffbcdfa9f07
[cicn.git] /
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 package com.metis.ccnx.ccnxsdk.metiscontrol;
17
18 import android.content.Context;
19 import android.content.Intent;
20 import android.os.AsyncTask;
21 import android.os.Bundle;
22 import android.os.Handler;
23 import android.support.design.widget.Snackbar;
24 import android.support.v4.app.Fragment;
25 import android.util.Log;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.AdapterView;
30 import android.widget.CompoundButton;
31 import android.widget.Spinner;
32 import android.widget.Switch;
33 import android.widget.TextView;
34
35 import com.metis.ccnx.ccnxsupportlibrary.Metis;
36
37 import org.json.JSONException;
38 import org.json.JSONObject;
39
40 import java.net.Inet4Address;
41 import java.net.InetAddress;
42 import java.nio.charset.Charset;
43 import java.util.List;
44
45
46 public class MetisStatusFragment extends Fragment implements IMetisNamedFragment {
47
48     private static final String ARG_PAGER_INDEX = "metisstatus_pager_number";
49     private static final String TAG = "CCNXMetis SF";
50
51     // TODO: Rename and change types of parameters
52     private int mPagerIndex;
53
54     private Switch mSwitchMetisOnOff = null;
55     private Spinner mSpinnerLogLevel = null;
56     private Switch mSwitchContentStoreOnOff = null;
57     private TextView mTVNumInterests = null;
58     private TextView mTVNumContentObjects = null;
59     private TextView mTVNumInterestReturns = null;
60     private TextView mTVNumControlMessages = null;
61     private TextView mTVNumPITEntries = null;
62     private TextView mPathTextView = null;
63
64     // Stats counters, updated by background task.
65     private long mNumInterests = 0;
66     private long mNumCOs = 0;
67     private long mNumInterestReturns = 0;
68     private long mNumControl = 0;
69     private long mNumPITENtries = 0;
70
71     private boolean mIsStatsQueryRunning = false;
72
73
74     //private PortalFactory mPortalFactory = null;
75
76     private OnFragmentVisibleListener mListener;
77
78
79     /**
80      * Create a Handler and a Runnable to be called every few seconds to query
81      * Metis (when running) for stats.
82      */
83     private Handler mStatusUpdaterHandler = new Handler();
84     private Runnable mStatusUpdateRunnable = new Runnable() {
85         @Override
86         public void run() {
87             // This runs on the main thread, so start an AsyncTask
88             // Repeat this the same runnable code block again another few seconds
89             //new GetStatusTask(null).execute(mPortalFactory);
90             //if (mIsStatsQueryRunning) {
91                 //mStatusUpdaterHandler.postDelayed(mStatusUpdateRunnable, 2 * 1000);
92             //}
93         }
94     };
95
96
97     public MetisStatusFragment() {
98         // Required empty public constructor
99     }
100
101     /**
102      * Use this factory method to create a new instance of
103      * this fragment using the provided parameters.
104      *
105      * @return A new instance of fragment MetisStatusFragment.
106      */
107     // TODO: Rename and change types and number of parameters
108     public static MetisStatusFragment newInstance(int pagerIndex) {
109         MetisStatusFragment fragment = new MetisStatusFragment();
110         Bundle args = new Bundle();
111         args.putInt(ARG_PAGER_INDEX, pagerIndex);
112
113         fragment.setArguments(args);
114
115         return fragment;
116     }
117
118     @Override
119     public void onStart() {
120         Metis metis = Metis.getInstance();
121         mSwitchMetisOnOff.setChecked(metis.isRunning());
122         super.onStart();
123     }
124
125
126     @Override
127     public void onCreate(Bundle savedInstanceState) {
128         super.onCreate(savedInstanceState);
129         if (getArguments() != null) {
130             mPagerIndex = getArguments().getInt(ARG_PAGER_INDEX);
131         }
132
133
134         Log.d(TAG, "Creating new PortalFactory");
135         //Identity identity = CCNxUtils.createCCNxIdentity(getContext(),
136         //        "password", "ccnxsdkdemo", 1024, 30);
137         //mPortalFactory = new PortalFactory(identity);
138     }
139
140
141
142     @Override
143     public View onCreateView(LayoutInflater inflater, ViewGroup container,
144                              Bundle savedInstanceState) {
145         // Inflate the layout for this fragment
146         View view = inflater.inflate(R.layout.fragment_metis_status, container, false);
147
148         mSwitchMetisOnOff = (Switch) view.findViewById(R.id.switchMetisOnOff);
149         mSwitchContentStoreOnOff = (Switch) view.findViewById(R.id.switchMetisContentStoreOnOff);
150         mSpinnerLogLevel = (Spinner) view.findViewById(R.id.spinnerMetisLoggingLevel);
151         mPathTextView = (TextView) view.findViewById(R.id.pathText) ;
152
153         mSpinnerLogLevel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
154             @Override
155             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
156                 String loggingLevel = mSpinnerLogLevel.getSelectedItem().toString();
157                 updateMetisLoggingLevel(loggingLevel);
158             }
159
160             @Override
161             public void onNothingSelected(AdapterView<?> parent) {
162
163             }
164         });
165
166         mSwitchMetisOnOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
167             @Override
168             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
169                 if (isChecked) {
170                     startMetis();
171                     //mSpinnerLogLevel.setEnabled(true);
172                     //Log.d(TAG, "################# Start periodic query for stats");
173                     //if (!mIsStatsQueryRunning) {
174                     //    mStatusUpdaterHandler.postDelayed(mStatusUpdateRunnable, 500);
175                      //   mIsStatsQueryRunning = true;
176                      //   String loggingLevel = mSpinnerLogLevel.getSelectedItem().toString();
177                      //   if (!loggingLevel.equalsIgnoreCase("off")) {
178                      //       updateMetisLoggingLevel(loggingLevel);
179                      //   }
180                     //}
181                 } else {
182                     Log.d(TAG, "################# Stop periodic query for stats");
183                     //mStatusUpdaterHandler.removeCallbacks(mStatusUpdateRunnable);
184                     //mIsStatsQueryRunning = false;
185                     stopMetis();
186                     //mSpinnerLogLevel.setEnabled(false);
187                     //mSpinnerLogLevel.setSelection(0);
188                 }
189             }
190         });
191
192         mTVNumInterests = (TextView) view.findViewById(R.id.tvStatsNumInterests);
193         mTVNumContentObjects = (TextView) view.findViewById(R.id.tvStatsNumContentObjects);
194         mTVNumInterestReturns = (TextView) view.findViewById(R.id.tvStatsNumInterestReturns);
195         mTVNumControlMessages = (TextView) view.findViewById(R.id.tvStatsNumControl);
196         mTVNumPITEntries = (TextView) view.findViewById(R.id.tvStatsPITSize);
197
198         mTVNumInterests.setText(String.valueOf(mNumInterests));
199         mTVNumContentObjects.setText(String.valueOf(mNumCOs));
200         mTVNumControlMessages.setText(String.valueOf(mNumControl));
201         mTVNumInterestReturns.setText(String.valueOf(mNumInterestReturns));
202         mTVNumPITEntries.setText("");
203
204         return view;
205     }
206
207     private void startMetis() {
208         mPathTextView.setEnabled(false);
209         Metis metis = Metis.getInstance();
210         if (!metis.isRunning()) {
211             Intent intent = new Intent(getActivity(), MetisService.class);
212             intent.putExtra("path", mPathTextView.getText());
213             getActivity().startService(intent);
214
215             new Handler().postDelayed(new Runnable() {
216                 @Override
217                 public void run() {
218                     createExternalListeners();
219                 }
220             }, 1000);
221         }
222     }
223
224     private void stopMetis() {
225         mPathTextView.setEnabled(true);
226         Intent intent = new Intent(getActivity(), MetisService.class);
227
228         getActivity().stopService(intent);
229
230     }
231
232     private void updateMetisLoggingLevel(String loggingLevel) {
233         /*Metis metis = Metis.getInstance();
234         if (metis.isRunning()) {
235             // Send an Interest control message to Metis with the new logging level.
236             String commandURI = MetisConstants.CCNxNameMetisCommand_Set + "/" + MetisConstants.MetisCommand_LogLevel + "/" + loggingLevel;
237             Name name = new Name(commandURI);
238             SendInterestTask task = new SendInterestTask(name, null, new SendInterestTask.OnInterestSentListener() {
239                 @Override
240                 public void onInterestSent(Message message) {
241                     if (message instanceof ContentObject) {
242
243                         String responseString = new String(((ContentObject) message).payload());
244                         Snackbar snackbar = Snackbar
245                                 .make(mSwitchMetisOnOff, responseString, Snackbar.LENGTH_SHORT);
246
247                         snackbar.show();
248                     } else {
249                         Log.d(TAG, "Unexpected non-Content response from sent Interest");
250                     }
251                 }
252             });
253
254             task.execute(mPortalFactory);
255         }*/
256     }
257
258     private void createExternalListeners() {
259
260         /*Metis metis = Metis.getInstance();
261
262         if (metis.isRunning()) {
263
264             List<InetAddress> ipAddresses = CCNxUtils.getLocalIpAddress();
265
266             for (InetAddress addr : ipAddresses) {
267
268                 // For the moment, just listen on the IPV4 addresses. The V6 addresses should work,
269                 // but it's not yet tested.
270
271                 if (addr instanceof Inet4Address) {
272
273                     String ipAddress = addr.getHostAddress();
274
275                     Log.d(TAG, "Adding external listener on: " + ipAddress);
276
277                     String linkURI = "tcp://" + ipAddress + ":" + MetisConstants.MetisDefaultListenerPort + "/listener";
278
279                     Name name = new Name(MetisConstants.CCNxNameMetisCommand_LinkConnect);
280
281                     SendInterestTask task = new SendInterestTask(name, linkURI.getBytes(), new SendInterestTask.OnInterestSentListener() {
282                         @Override
283                         public void onInterestSent(Message message) {
284                             if (message instanceof ContentObject) {
285
286                                 String responseString = new String(((ContentObject) message).payload());
287                                 Snackbar snackbar = Snackbar
288                                         .make(mSwitchMetisOnOff, responseString, Snackbar.LENGTH_SHORT);
289
290                                 snackbar.show();
291                             } else {
292                                 Log.d(TAG, "Unexpected non-Content response from sent Interest");
293                             }
294                         }
295                     });
296
297                     task.execute(mPortalFactory);
298                 }
299             }
300         }*/
301     }
302
303
304     @Override
305     public void onAttach(Context context) {
306         super.onAttach(context);
307         if (context instanceof OnFragmentVisibleListener) {
308             mListener = (OnFragmentVisibleListener) context;
309         } else {
310             throw new RuntimeException(context.toString()
311                     + " must implement OnFragmentInteractionListener");
312         }
313     }
314
315
316     @Override
317     public void setUserVisibleHint(boolean isVisibleToUser) {
318         super.setUserVisibleHint(isVisibleToUser);
319         Metis metis = Metis.getInstance();
320
321         if (isVisibleToUser) {
322             mListener.onFragmentVisible(this);
323
324             if (metis.isRunning()) {
325                 // Begin updating stats.
326                 if (!mIsStatsQueryRunning) {
327                     mStatusUpdaterHandler.postDelayed(mStatusUpdateRunnable, 100);
328                     mIsStatsQueryRunning = true;
329                 }
330             }
331         } else {
332             mStatusUpdaterHandler.removeCallbacks(mStatusUpdateRunnable);
333             mIsStatsQueryRunning = false;
334         }
335     }
336
337     @Override
338     public void onDetach() {
339         mStatusUpdaterHandler.removeCallbacks(mStatusUpdateRunnable);
340         mIsStatsQueryRunning = false;
341         super.onDetach();
342         mListener = null;
343     }
344
345     @Override
346     public String getFragmentName() {
347         return "Status";
348     }
349
350     public interface OnFragmentVisibleListener {
351         // TODO: Update argument type and name
352         void onFragmentVisible(Fragment which);
353     }
354
355     /*private class GetStatusTask extends AsyncTask<PortalFactory, String, Integer> {
356
357         private boolean mSuccess = false;
358         private PortalFactory mPortalFactory = null;
359
360
361         public GetStatusTask(String unused) {
362         }
363
364         @Override
365         protected Integer doInBackground(PortalFactory... args) {
366             Thread.currentThread().setName("GetStatusTask-Async");
367
368             mPortalFactory = args[0];
369             try {
370                 Name controlName = new Name(MetisConstants.CCNxNameMetisCommand_Stats);
371
372                 Interest interest = new Interest(controlName);
373
374                 try {
375                     Portal portal = mPortalFactory.getPortal();
376
377                     portal.send(interest, 0L);
378
379                     Message m = portal.receive(0L);
380
381                     if (m instanceof ContentObject) {
382                         mSuccess = true;
383                         ContentObject co = (ContentObject) m;
384                         byte[] payload = co.payload();
385
386                         if (payload != null) {
387                             String jsonString = new String(payload, Charset.defaultCharset());
388                             //Log.d(TAG, "Received: XX " + jsonString + " XX");
389                             try {
390                                 JSONObject jo = new JSONObject(jsonString);
391                                 //Log.d(TAG, "JSON2: " + jo.toString(2));
392
393                                 mNumInterests = jo.getLong("numProcessedInterests");
394                                 mNumCOs = jo.getLong("numProcessedContentObjects");
395                                 mNumControl = jo.getLong("numProcessedControlMessages");
396                                 mNumInterestReturns = jo.getLong("numProcessedInterestReturns");
397                             } catch (JSONException ex) {
398                                 Log.e(TAG, "Could not parse returned JSON: " + ex.getMessage());
399                             }
400                         }
401                     }
402                     portal.close();
403                 } catch (Portal.CommunicationsError ex) {
404                     Log.e(TAG, "Error sending AddLink command: " + ex.getMessage());
405                 }
406             } catch (Exception ex) {
407                 Log.e(TAG, "Error adding link: " + ex.getMessage());
408             }
409
410             return 1;
411         }
412
413         @Override
414         protected void onPostExecute(Integer ignored) {
415
416             if (mSuccess) {
417                 mTVNumInterests.setText(String.valueOf(mNumInterests));
418                 mTVNumContentObjects.setText(String.valueOf(mNumCOs));
419                 mTVNumControlMessages.setText(String.valueOf(mNumControl));
420                 mTVNumInterestReturns.setText(String.valueOf(mNumInterestReturns));
421                 mTVNumPITEntries.setText("");
422             }
423         }
424     }*/
425
426 }