Android Open Source - looking-glass Auth Answer Service






From Project

Back to project page looking-glass.

License

The source code is released under:

Apache License

If you think the Android project looking-glass listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package ca.orospakr.lookingglass;
//  ww w . ja v  a 2 s  . c om
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

import javax.inject.Inject;

/**
 * Responsible for getting the answer from the notifications kicked up by the SessionManager over in SessionManager.
 */
public class AuthAnswerService extends Service {

    public static final String FIELD_AUTHORITY_ARGUMENT = "authority";
    public static final String FIELD_ANSWER = "answer";
    public static final String FIELD_SESSION = "session";

    private static final String LOG_TAG = "LookingGlass/AuthAnswerService";

    // SINGLETON, expected to live the lifetime of the :sync process.  somewhere better to put it than static, which is kind of sucky?  make it a singleton in the dagger graph?
    public static ConcurrentHashMap<String, FutureTask<String>> blockedRequests = new ConcurrentHashMap<String, FutureTask<String>>();

    @Inject
    public SessionManager sessionManager;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        ((LookingGlassApp) getApplication()).inject(this);
        int r = super.onStartCommand(intent, flags, startId);

        Log.d(LOG_TAG, "GOT MY SESSION MANAGER: " + sessionManager);

        // here I'll get my answer from the notification.  pull the value back out!

        Bundle extras = intent.getExtras();

        String authority = extras.getString(FIELD_AUTHORITY_ARGUMENT);
        String answer = extras.getString(FIELD_ANSWER);
        String authToken = extras.getString(FIELD_SESSION);
        Log.d(LOG_TAG, extras.toString());

        Log.d(LOG_TAG, "GOT REQUEST TO " + answer + ": " + authority);

        // TODO write the setting via SessionManager!

        SessionManager.Session session = sessionManager.retrieveSession(authToken);
        // set allow/deny on session
        if(answer.equals("allow")) {
            session.permittedAuthorities.add(authority);
        } else {
            session.disallowedAuthorities.add(authority);
        }
        // block!
        // remove the notification
        sessionManager.saveSession(authToken, session);

        // then resolve any blocked requests
        blockedRequests.get(authority);

        return r;
    }

    public static Future putUpNotification(Context context, String authToken, String authority, FutureValue<String> cb) {
        Notification.BigTextStyle style = new Notification.BigTextStyle();
        style.bigText("A device would like to look at " + authority);
        style.setBigContentTitle("Looking Glass - Request");

        Notification.Builder notificationBuilder = new Notification.Builder(context);
        notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Looking Glass - Request")
                .setContentText("A device would like to look at " + authority)
                .setTicker("Allow someone to look at " + authority + "?")
                .setStyle(style);


        Intent denyIntent = new Intent();
        denyIntent.setClass(context, AuthAnswerService.class);

        Bundle denyExtras = new Bundle();
        denyExtras.putString(FIELD_AUTHORITY_ARGUMENT, authority);
        denyExtras.putString(FIELD_ANSWER, "deny");
        denyExtras.putString(FIELD_SESSION, authToken);
        denyIntent.putExtras(denyExtras);

        Intent allowIntent = new Intent();
        allowIntent.setClass(context, AuthAnswerService.class);
        Bundle allowExtras = new Bundle();
        allowExtras.putString(FIELD_ANSWER, "allow");
        allowExtras.putString(FIELD_AUTHORITY_ARGUMENT, authority);
        allowExtras.putString(FIELD_SESSION, authToken);
        allowIntent.putExtras(allowExtras);

        // with this arrangement, this will cause existing notifications for another service to be destroyed if the user hasn't answered the yet.  Could Fix this by setting a request code that is a hash of the authority.
        PendingIntent denyAction = PendingIntent.getService(context, 0, denyIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        PendingIntent allowAction = PendingIntent.getService(context, 1, allowIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        notificationBuilder.addAction(android.R.drawable.ic_lock_lock, "Deny", denyAction);
        notificationBuilder.addAction(R.drawable.ic_cab_done_holo_dark, "Allow", allowAction);
        NotificationManager notificationThingy = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationThingy.notify(56356, notificationBuilder.build());

        final Object answerBlockLock = new Object();

        // first, create a callback that waits above.  however, it can only be for returning the value to the blocked consumer.  I still want the update of the setting to occur, in case the pendingintent is finally fired long after the process is gone.

        Callable stubRunnable = new Callable() {
            @Override
            public Object call() {
                throw new RuntimeException("Using FutureTask as a custom waitable answer source; not using the scheduling feature.");
            }
        };

        FutureTask<String> f = new FutureTask<String>(stubRunnable) {
            public void _set(String value) {
                super.set(value);
            }
        };

        // answerBlockLock.notifyAll();
        return f;
    }
}




Java Source Code List

ca.orospakr.lookingglass.AndroidModule.java
ca.orospakr.lookingglass.AuthAnswerService.java
ca.orospakr.lookingglass.FutureValue.java
ca.orospakr.lookingglass.HttpService.java
ca.orospakr.lookingglass.LookingGlassApp.java
ca.orospakr.lookingglass.LookingGlassModule.java
ca.orospakr.lookingglass.MainActivity.java
ca.orospakr.lookingglass.SessionManager.java