| // Copyright 2015 The Vanadium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package io.v.discoverysample; |
| |
| import android.app.Activity; |
| import android.content.Intent; |
| import android.os.Bundle; |
| import android.view.Menu; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.widget.Button; |
| import android.widget.ListView; |
| import android.widget.Toast; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import io.v.android.libs.discovery.ble.BlePlugin; |
| import io.v.android.libs.security.BlessingsManager; |
| import io.v.android.v23.V; |
| import io.v.android.v23.services.blessing.BlessingCreationException; |
| import io.v.android.v23.services.blessing.BlessingService; |
| import io.v.impl.google.lib.discovery.UUIDUtil; |
| import io.v.v23.context.CancelableVContext; |
| import io.v.v23.context.VContext; |
| import io.v.v23.discovery.Attributes; |
| import io.v.v23.discovery.Service; |
| import io.v.v23.security.Blessings; |
| import io.v.v23.verror.VException; |
| import io.v.v23.vom.VomUtil; |
| import io.v.x.ref.lib.discovery.Advertisement; |
| import io.v.x.ref.lib.discovery.EncryptionAlgorithm; |
| |
| |
| public class MainActivity extends Activity { |
| |
| private static final int BLESSINGS_REQUEST = 1; |
| private Button chooseBlessingsButton; |
| private Button scanButton; |
| private Button advertiseButton; |
| private Blessings blessings; |
| private BlePlugin plugin; |
| |
| private VContext rootCtx; |
| private CancelableVContext scanCtx; |
| private CancelableVContext advCtx; |
| |
| private boolean isScanning; |
| private boolean isAdvertising; |
| |
| private ScanHandlerAdapter adapter; |
| |
| private Advertisement advertisement; |
| |
| @Override |
| protected void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| rootCtx = V.init(this); |
| isScanning = false; |
| isAdvertising = false; |
| |
| setContentView(R.layout.activity_main); |
| chooseBlessingsButton = (Button)findViewById(R.id.blessingsButton); |
| chooseBlessingsButton.setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View view) { |
| fetchBlessings(false); |
| } |
| }); |
| |
| scanButton = (Button)findViewById(R.id.scanForService); |
| scanButton.setEnabled(false); |
| scanButton.setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View view) { |
| flipScan(); |
| } |
| }); |
| |
| advertiseButton = (Button) findViewById(R.id.advertiseButton); |
| advertiseButton.setEnabled(false); |
| advertiseButton.setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View view) { |
| flipAdvertise(); |
| } |
| }); |
| |
| byte[] instanceId = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15}; |
| Attributes attrs = new Attributes(); |
| attrs.put("foo", "bar"); |
| List<String> addrs = new ArrayList<>(); |
| addrs.add("localhost:2000"); |
| String interfaceName = "v.io/x/ref.Interface"; |
| advertisement = new Advertisement( |
| new Service(instanceId, "Android instance", |
| interfaceName, attrs, addrs), |
| UUIDUtil.UUIDToUuid(UUIDUtil.UUIDForInterfaceName(interfaceName)), |
| new EncryptionAlgorithm(0), |
| null, |
| false); |
| adapter = new ScanHandlerAdapter(this); |
| ListView devices = (ListView) findViewById(R.id.list_view); |
| devices.setAdapter(adapter); |
| } |
| |
| @Override |
| public boolean onCreateOptionsMenu(Menu menu) { |
| // Inflate the menu; this adds items to the action bar if it is present. |
| getMenuInflater().inflate(R.menu.menu_main, menu); |
| return true; |
| } |
| |
| private void flipAdvertise() { |
| if (plugin == null) { |
| plugin = new BlePlugin(this); |
| } |
| |
| if (!isAdvertising) { |
| isAdvertising = true; |
| |
| advCtx = rootCtx.withCancel(); |
| try { |
| plugin.addAdvertisement(advCtx, advertisement); |
| advertiseButton.setText("Stop Advertisement"); |
| } catch (IOException e) { |
| advCtx.cancel(); |
| isAdvertising = false; |
| } |
| } else { |
| isAdvertising = false; |
| advCtx.cancel(); |
| advertiseButton.setText("Advertise"); |
| } |
| } |
| private void flipScan() { |
| if (plugin == null) { |
| plugin = new BlePlugin(this); |
| } |
| if (!isScanning) { |
| scanCtx = rootCtx.withCancel(); |
| plugin.addScanner(scanCtx, |
| UUIDUtil.UUIDForInterfaceName("v.io/x/ref.Interface"), |
| adapter); |
| isScanning = true; |
| scanButton.setText("Stop scanning"); |
| } else { |
| isScanning = false; |
| scanCtx.cancel(); |
| scanButton.setText("Start Scan"); |
| } |
| } |
| |
| private void fetchBlessings(boolean startScan) { |
| Intent intent = BlessingService.newBlessingIntent(this); |
| startActivityForResult(intent, BLESSINGS_REQUEST); |
| } |
| |
| @Override |
| protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
| switch (requestCode) { |
| case BLESSINGS_REQUEST: |
| try { |
| // The Account Manager will pass us the blessings to use as |
| // an array of bytes. Use VomUtil to decode them... |
| byte[] blessingsVom = |
| BlessingService.extractBlessingReply(resultCode, data); |
| blessings = (Blessings) VomUtil.decode(blessingsVom, Blessings.class); |
| BlessingsManager.addBlessings(this, blessings); |
| Toast.makeText(this, "Success, ready to listen!", |
| Toast.LENGTH_SHORT).show(); |
| |
| // Enable the "start service" button. |
| scanButton.setEnabled(true); |
| advertiseButton.setEnabled(true); |
| } catch (BlessingCreationException e) { |
| String msg = "Couldn't create blessing: " + e.getMessage(); |
| Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); |
| } catch (VException e) { |
| String msg = "Couldn't store blessing: " + e.getMessage(); |
| Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); |
| } |
| return; |
| } |
| } |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| // Handle action bar item clicks here. The action bar will |
| // automatically handle clicks on the Home/Up button, so long |
| // as you specify a parent activity in AndroidManifest.xml. |
| int id = item.getItemId(); |
| |
| //noinspection SimplifiableIfStatement |
| if (id == R.id.action_settings) { |
| return true; |
| } |
| |
| return super.onOptionsItemSelected(item); |
| } |
| } |