content: /**
   * 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.widget;
  
  import android.content.Intent;
  import android.os.Bundle;
  import android.support.v4.app.Fragment;
  import com.facebook.Session;
  import com.facebook.SessionLoginBehavior;
  import com.facebook.SessionState;
  import com.facebook.internal.SessionAuthorizationType;
  import com.facebook.internal.SessionTracker;
  
  import java.util.Date;
  import java.util.List;
  
  /**
   * <p>Basic implementation of a Fragment that uses a Session to perform 
   * Single Sign On (SSO). This class is package private, and is not intended
   * to be consumed by external applications.</p>
   * 
   * <p>The method {@link android.support.v4.app.Fragment#onActivityResult} is
   * used to manage the session information, so if you override it in a subclass, 
   * be sure to call {@code super.onActivityResult}.</p>
   * 
   * <p>The methods in this class are not thread-safe.</p>
   */
  class FacebookFragment extends Fragment {
  
      private SessionTracker sessionTracker;
  
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
          super.onActivityCreated(savedInstanceState);
          sessionTracker = new SessionTracker(getActivity(), new DefaultSessionStatusCallback());
      }
      
      /**
       * Called when the activity that was launched exits. This method manages session
       * information when a session is opened. If this method is overridden in subclasses,
       * be sure to call {@code super.onActivityResult(...)} first.
       */
      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          sessionTracker.getSession().onActivityResult(this.getActivity(), requestCode, resultCode, data);
      }
  
      @Override
      public void onDestroy() {
          super.onDestroy();
          sessionTracker.stopTracking();
      }
  
      /**
       * Use the supplied Session object instead of the active Session.
       *
       * @param newSession the Session object to use
       */
      public void setSession(Session newSession) {
          if (sessionTracker != null) {
              sessionTracker.setSession(newSession);
          }
      }
  
      // METHOD TO BE OVERRIDDEN
      
      /**
       * Called when the session state changes. Override this method to take action
       * on session state changes.
       * 
       * @param state the new state
       * @param exception any exceptions that occurred during the state change
       */
      protected void onSessionStateChange(SessionState state, Exception exception) {
      }
  
      // ACCESSORS (CANNOT BE OVERRIDDEN)
      
      /**
       * Gets the current Session.
       * 
       * @return the current Session object.
       */
      protected final Session getSession() {
          if (sessionTracker != null) {
              return sessionTracker.getSession();
          }
          return null;
      }
  
      /**
       * Determines whether the current session is open.
       * 
       * @return true if the current session is open
       */
      protected final boolean isSessionOpen() {
          if (sessionTracker != null) {
              return sessionTracker.getOpenSession() != null;
          }
          return false;
      }
      
      /**
       * Gets the current state of the session or null if no session has been created.
       * 
       * @return the current state of the session
       */
      protected final SessionState getSessionState() {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getSession();
              return (currentSession != null) ? currentSession.getState() : null;
          }
          return null;
      }
      
      /**
       * Gets the access token associated with the current session or null if no 
       * session has been created.
       * 
       * @return the access token
       */
      protected final String getAccessToken() {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getOpenSession();
              return (currentSession != null) ? currentSession.getAccessToken() : null;
          }
          return null;
      }
  
      /**
       * Gets the date at which the current session will expire or null if no session 
       * has been created.
       * 
       * @return the date at which the current session will expire
       */
      protected final Date getExpirationDate() {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getOpenSession();
              return (currentSession != null) ? currentSession.getExpirationDate() : null;
          }
          return null;
      }
      
      /**
       * Closes the current session.
       */
      protected final void closeSession() {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getOpenSession();
              if (currentSession != null) {
                  currentSession.close();
              }
          }
      }
      
      /**
       * Closes the current session as well as clearing the token cache.
       */
      protected final void closeSessionAndClearTokenInformation() {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getOpenSession();
              if (currentSession != null) {
                  currentSession.closeAndClearTokenInformation();
              }
          }
      }
      
      /**
       * Gets the permissions associated with the current session or null if no session 
       * has been created.
       * 
       * @return the permissions associated with the current session
       */
      protected final List<String> getSessionPermissions() {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getSession();
              return (currentSession != null) ? currentSession.getPermissions() : null;
          }
          return null;
      }
  
      /**
       * Opens a new session. This method will use the application id from
       * the associated meta-data value and an empty list of permissions.
       */
      protected final void openSession() {
          openSessionForRead(null, null);
      }
  
      /**
       * Opens a new session with read permissions. If either applicationID or permissions
       * is null, this method will default to using the values from the associated
       * meta-data value and an empty list respectively.
       *
       * @param applicationId the applicationID, can be null
       * @param permissions the permissions list, can be null
       */
      protected final void openSessionForRead(String applicationId, List<String> permissions) {
          openSessionForRead(applicationId, permissions, SessionLoginBehavior.SSO_WITH_FALLBACK,
                  Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE);
      }
  
      /**
       * Opens a new session with read permissions. If either applicationID or permissions
       * is null, this method will default to using the values from the associated
       * meta-data value and an empty list respectively.
       *
       * @param applicationId the applicationID, can be null
       * @param permissions the permissions list, can be null
       * @param behavior the login behavior to use with the session
       * @param activityCode the activity code to use for the SSO activity
       */
      protected final void openSessionForRead(String applicationId, List<String> permissions,
              SessionLoginBehavior behavior, int activityCode) {
          openSession(applicationId, permissions, behavior, activityCode, SessionAuthorizationType.READ);
      }
  
      /**
       * Opens a new session with publish permissions. If either applicationID is null,
       * this method will default to using the value from the associated
       * meta-data value. The permissions list cannot be null.
       *
       * @param applicationId the applicationID, can be null
       * @param permissions the permissions list, cannot be null
       */
      protected final void openSessionForPublish(String applicationId, List<String> permissions) {
          openSessionForPublish(applicationId, permissions, SessionLoginBehavior.SSO_WITH_FALLBACK,
                  Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE);
      }
  
      /**
       * Opens a new session with publish permissions. If either applicationID is null,
       * this method will default to using the value from the associated
       * meta-data value. The permissions list cannot be null.
       *
       * @param applicationId the applicationID, can be null
       * @param permissions the permissions list, cannot be null
       * @param behavior the login behavior to use with the session
       * @param activityCode the activity code to use for the SSO activity
       */
      protected final void openSessionForPublish(String applicationId, List<String> permissions,
              SessionLoginBehavior behavior, int activityCode) {
          openSession(applicationId, permissions, behavior, activityCode, SessionAuthorizationType.PUBLISH);
      }
  
      private void openSession(String applicationId, List<String> permissions,
              SessionLoginBehavior behavior, int activityCode, SessionAuthorizationType authType) {
          if (sessionTracker != null) {
              Session currentSession = sessionTracker.getSession();
              if (currentSession == null || currentSession.getState().isClosed()) {
                  Session session = new Session.Builder(getActivity()).setApplicationId(applicationId).build();
                  Session.setActiveSession(session);
                  currentSession = session;
              }
              if (!currentSession.isOpened()) {
                  Session.OpenRequest openRequest = new Session.OpenRequest(this).
                          setPermissions(permissions).
                          setLoginBehavior(behavior).
                          setRequestCode(activityCode);
                  if (SessionAuthorizationType.PUBLISH.equals(authType)) {
                      currentSession.openForPublish(openRequest);
                  } else {
                      currentSession.openForRead(openRequest);
                  }
              }
          }
      }
  
      /**
       * The default callback implementation for the session.
       */
      private class DefaultSessionStatusCallback implements Session.StatusCallback {
  
          @Override
          public void call(Session session, 
                           SessionState state,
                           Exception exception) {
              FacebookFragment.this.onSessionStateChange(state, exception);
          }
          
      }
  }
  