Java tutorial
// 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.location; import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Criteria; import android.location.Location; import android.location.LocationManager; import android.os.IBinder; import android.util.Log; import android.widget.Toast; import com.google.common.collect.Lists; import java.util.Arrays; import java.util.List; import io.v.android.v23.V; import io.v.v23.context.VContext; import io.v.v23.rpc.ListenSpec; import io.v.v23.rpc.Server; import io.v.v23.rpc.ServerCall; import io.v.v23.security.BlessingPattern; import io.v.v23.security.Blessings; import io.v.v23.security.VCertificate; import io.v.v23.security.VPrincipal; import io.v.v23.security.VSecurity; import io.v.v23.verror.VException; import io.v.v23.vom.VomUtil; public class LocationService extends Service { private static final String TAG = "LocationService"; VContext mBaseContext; @Override public int onStartCommand(Intent intent, int flags, int startId) { mBaseContext = V.init(this); String blessingsVom = intent.getStringExtra(LocationActivity.BLESSINGS_KEY); if (blessingsVom == null || blessingsVom.isEmpty()) { String msg = "Couldn't start LocationService: null or empty encoded blessings."; Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); Log.i(TAG, msg); return START_REDELIVER_INTENT; } try { Blessings blessings = (Blessings) VomUtil.decodeFromString(blessingsVom, Blessings.class); if (blessings == null) { String msg = "Couldn't start LocationService: null blessings."; Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); Log.i(TAG, msg); return START_REDELIVER_INTENT; } storeBlessings(blessings); startLocationService(determineMountPoint(blessings)); } catch (VException e) { String msg = "Couldn't start LocationService: " + e.getMessage(); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); Log.i(TAG, msg); } return START_REDELIVER_INTENT; } private void startLocationService(String mountPoint) throws VException { VeyronLocationService locationService = new VeyronLocationService( (LocationManager) getSystemService(Context.LOCATION_SERVICE)); ListenSpec spec = V.getListenSpec(mBaseContext).withProxy("proxy"); Log.i(TAG, "Mounting server at " + mountPoint); VContext ctx = V.withNewServer(V.withListenSpec(mBaseContext, spec), mountPoint, locationService, null); Server server = V.getServer(ctx); Log.i(TAG, "Listening on endpoints: " + Arrays.toString(server.getStatus().getEndpoints())); Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show(); } // Update vanadium state with the new blessings. private void storeBlessings(Blessings blessings) throws VException { VPrincipal p = V.getPrincipal(mBaseContext); p.blessingStore().setDefaultBlessings(blessings); p.blessingStore().set(blessings, new BlessingPattern("...")); VSecurity.addToRoots(p, blessings); } @Override public IBinder onBind(Intent intent) { // Binding not allowed. return null; } private static class VeyronLocationService implements LocationServer { private final LocationManager manager; private VeyronLocationService(LocationManager manager) { this.manager = manager; } @Override public LatLng get(VContext context, ServerCall call) throws VException { Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.NO_REQUIREMENT); String provider = manager.getBestProvider(criteria, true); if (provider == null || provider.isEmpty()) { throw new VException("Couldn't find any location providers on the device."); } Location location = manager.getLastKnownLocation(provider); if (location == null) { throw new VException("Got null location."); } return new LatLng(location.getLatitude(), location.getLongitude()); } } private static String determineMountPoint(Blessings blessings) { String name = userEmailFromBlessings(blessings); return name.isEmpty() ? "" : "users/" + name + "/location"; } private static String userEmailFromBlessings(Blessings blessings) { for (List<VCertificate> chain : blessings.getCertificateChains()) { for (VCertificate certificate : Lists.reverse(chain)) { if (certificate.getExtension().contains("@")) { return certificate.getExtension(); } } } Log.w(TAG, "Could not determine name from blessings '" + blessings + "'"); return ""; } }