Skip to content

Commit

Permalink
#8: created a class for saving the session, added dependencies for Rx…
Browse files Browse the repository at this point in the history
…Java 3.
  • Loading branch information
temnik15 committed Nov 8, 2020
1 parent f1a868b commit 6590144
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 2 deletions.
5 changes: 4 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

// https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxjava
implementation group: 'io.reactivex.rxjava3', name: 'rxjava', version: '3.0.7'
// https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxandroid
implementation group: 'io.reactivex.rxjava3', name: 'rxandroid', version: '3.0.0'
}
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:name=".HawkApp">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/so/codex/hawk/HawkApp.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package so.codex.hawk

import android.app.Application

class HawkApp: Application() {

override fun onCreate() {
super.onCreate()
SessionKeeper.init(applicationContext)
}
}
126 changes: 126 additions & 0 deletions app/src/main/java/so/codex/hawk/SessionKeeper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package so.codex.hawk

import android.content.Context
import android.content.SharedPreferences
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.subjects.BehaviorSubject
import so.codex.hawk.entity.Session
import so.codex.hawk.entity.Token

/**
* This class (singleton) is responsible for saving session data (accessToken,refreshToken, time).
*/
object SessionKeeper {
/**
* @property context An instance of the Context class. Used to access [SharedPreferences].
*/
private lateinit var context: Context

/**
* @property KEY_SESSION_PREF Key to get sharedPreferences from context.
*/
private const val KEY_SESSION_PREF = "SESSION_PREF"

/**
* @property KEY_ACCESS_TOKEN The key to get the access token value stored on the device.
*/
const val KEY_ACCESS_TOKEN = "ACCESS_TOKEN"

/**
* @property KEY_REFRESH_TOKEN The key to get the refresh token value stored on the device.
*/
const val KEY_REFRESH_TOKEN = "REFRESH_TOKEN"

/**
* @property KEY_TIME_SESSION A key for getting the value of the start time of
* the last session stored on the device.
*/
const val KEY_TIME_SESSION = "TIME_SESSION"

/**
* @property session Field for storing the [Session] instance while the application is running.
* The field is open for reading and closed for direct installation. To save
* a new instance of the session, use the .saveSession(newSession) methods.
*/
var session: Session = Session(Token("", ""), 0)
private set

/**
* @property prefSubject An instance of BehaviorSubject extending the Observable class and
* capable of sending updates to subscribers. When subscribed, sends
* the last session update. This instance sends out key-value pairs
* containing information about updating session elements.
*/
private val prefSubject: BehaviorSubject<Pair<String, String>> = BehaviorSubject.create()

/**
* [SessionKeeper] initialization method.
* Must be called 1 time at application start (In [HawkApp] class).
*
* @param context Must be an applicationContext to avoid memory leaks.
*/
fun init(context: Context) {
if(!this::context.isInitialized){
this.context = context
val preferences = context.getSharedPreferences(KEY_SESSION_PREF, Context.MODE_PRIVATE)
restoreSessionFromPref(preferences)
preferences.registerOnSharedPreferenceChangeListener { pref, key ->
val value = pref.getString(key, "")!!
prefSubject.onNext(key to value)
}
}
}

/**
* Method for updating a session instance while the application is running.
* The method also stores information about the new session in sharedPreferences.
*
* @param newSession An instance of the new session. Must be populated with [Token]
* and last update time.
*/
fun saveSession(newSession: Session) {
session = newSession
saveToSharedPref(session)
}

/**
* Method for adding observer to session update.
*
* @param observer An observer that will subscribe to the session update and will receive
* a key-value pair with each update for further use. When subscribing,
* the observer will receive the last session update and will continue
* to receive updates until the observable sends an .onComplete().
*/
fun subscribeToSessionUpdate(observer: Observer<Pair<String, String>>) {
prefSubject.subscribe(observer)
}

/**
* Session recovery method from sharedPreferences saved on the device.
*
* @param preferences sharedPreferences saved on the device.
* @see init
*/
private fun restoreSessionFromPref(preferences: SharedPreferences) {
val accessToken = preferences.getString(KEY_ACCESS_TOKEN, "")
val refreshToken = preferences.getString(KEY_REFRESH_TOKEN, "")
val timeStr = preferences.getString(KEY_TIME_SESSION, "0")
val time = timeStr!!.toLong()
if (accessToken.isNullOrBlank() or refreshToken.isNullOrBlank()) return
session = Session(Token(accessToken!!, refreshToken!!), time)
}

/**
* The method of saving the session to sharedPreferences stored on the device.
*
* @param session Session instance containing information about the new user session.
*/
private fun saveToSharedPref(session: Session) {
val editor = context.getSharedPreferences(KEY_SESSION_PREF, Context.MODE_PRIVATE).edit()
editor.putString(KEY_ACCESS_TOKEN, session.token.accessToken)
editor.putString(KEY_REFRESH_TOKEN, session.token.refreshToken)
editor.putString(KEY_TIME_SESSION, "${session.time}")
editor.apply()
}

}
4 changes: 4 additions & 0 deletions app/src/main/java/so/codex/hawk/entity/Session.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package so.codex.hawk.entity

data class Session(val token:Token,val time:Long)
data class Token(val accessToken: String, val refreshToken: String)

0 comments on commit 6590144

Please sign in to comment.