Blame | Last modification | View Log | RSS feed
/*** Copyright 2010-present Facebook.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.facebook.internal;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.support.v4.content.LocalBroadcastManager;import com.facebook.Session;import com.facebook.SessionState;/*** com.facebook.internal is solely for the use of other packages within the Facebook SDK for Android. Use of* any of the classes in this package is unsupported, and they may be modified or removed without warning at* any time.*/public class SessionTracker {private Session session;private final Session.StatusCallback callback;private final BroadcastReceiver receiver;private final LocalBroadcastManager broadcastManager;private boolean isTracking = false;/*** Constructs a SessionTracker to track the active Session object.** @param context the context object.* @param callback the callback to use whenever the active Session's* state changes*/public SessionTracker(Context context, Session.StatusCallback callback) {this(context, callback, null);}/*** Constructs a SessionTracker to track the Session object passed in.* If the Session is null, then it will track the active Session instead.** @param context the context object.* @param callback the callback to use whenever the Session's state changes* @param session the Session object to track*/SessionTracker(Context context, Session.StatusCallback callback, Session session) {this(context, callback, session, true);}/*** Constructs a SessionTracker to track the Session object passed in.* If the Session is null, then it will track the active Session instead.** @param context the context object.* @param callback the callback to use whenever the Session's state changes* @param session the Session object to track* @param startTracking whether to start tracking the Session right away*/public SessionTracker(Context context, Session.StatusCallback callback, Session session, boolean startTracking) {this.callback = new CallbackWrapper(callback);this.session = session;this.receiver = new ActiveSessionBroadcastReceiver();this.broadcastManager = LocalBroadcastManager.getInstance(context);if (startTracking) {startTracking();}}/*** Returns the current Session that's being tracked.** @return the current Session associated with this tracker*/public Session getSession() {return (session == null) ? Session.getActiveSession() : session;}/*** Returns the current Session that's being tracked if it's open,* otherwise returns null.** @return the current Session if it's open, otherwise returns null*/public Session getOpenSession() {Session openSession = getSession();if (openSession != null && openSession.isOpened()) {return openSession;}return null;}/*** Set the Session object to track.** @param newSession the new Session object to track*/public void setSession(Session newSession) {if (newSession == null) {if (session != null) {// We're current tracking a Session. Remove the callback// and start tracking the active Session.session.removeCallback(callback);session = null;addBroadcastReceiver();if (getSession() != null) {getSession().addCallback(callback);}}} else {if (session == null) {// We're currently tracking the active Session, but will be// switching to tracking a different Session object.Session activeSession = Session.getActiveSession();if (activeSession != null) {activeSession.removeCallback(callback);}broadcastManager.unregisterReceiver(receiver);} else {// We're currently tracking a Session, but are now switching// to a new Session, so we remove the callback from the old// Session, and add it to the new one.session.removeCallback(callback);}session = newSession;session.addCallback(callback);}}/*** Start tracking the Session (either active or the one given).*/public void startTracking() {if (isTracking) {return;}if (this.session == null) {addBroadcastReceiver();}// if the session is not null, then add the callback to it right awayif (getSession() != null) {getSession().addCallback(callback);}isTracking = true;}/*** Stop tracking the Session and remove any callbacks attached* to those sessions.*/public void stopTracking() {if (!isTracking) {return;}Session session = getSession();if (session != null) {session.removeCallback(callback);}broadcastManager.unregisterReceiver(receiver);isTracking = false;}/*** Returns whether it's currently tracking the Session.** @return true if currently tracking the Session*/public boolean isTracking() {return isTracking;}/*** Returns whether it's currently tracking the active Session.** @return true if the currently tracked session is the active Session.*/public boolean isTrackingActiveSession() {return session == null;}private void addBroadcastReceiver() {IntentFilter filter = new IntentFilter();filter.addAction(Session.ACTION_ACTIVE_SESSION_SET);filter.addAction(Session.ACTION_ACTIVE_SESSION_UNSET);// Add a broadcast receiver to listen to when the active Session// is set or unset, and add/remove our callback as appropriatebroadcastManager.registerReceiver(receiver, filter);}/*** The BroadcastReceiver implementation that either adds or removes the callback* from the active Session object as it's SET or UNSET.*/private class ActiveSessionBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (Session.ACTION_ACTIVE_SESSION_SET.equals(intent.getAction())) {Session session = Session.getActiveSession();if (session != null) {session.addCallback(SessionTracker.this.callback);}}}}private class CallbackWrapper implements Session.StatusCallback {private final Session.StatusCallback wrapped;public CallbackWrapper(Session.StatusCallback wrapped) {this.wrapped = wrapped;}@Overridepublic void call(Session session, SessionState state, Exception exception) {if (wrapped != null && isTracking()) {wrapped.call(session, state, exception);}// if we're not tracking the Active Session, and the current session// is closed, then start tracking the Active Session.if (session == SessionTracker.this.session && state.isClosed()) {setSession(null);}}}}