blob: affb56a0b164ce3235b17561105f0671ca5195a7 [file] [log] [blame]
// 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);
}
}