Skip to content

Commit

Permalink
Merge branch '36-introduce-setup-for-cloudsdk' into 'master'
Browse files Browse the repository at this point in the history
Resolve "Introduce setup for CloudSDK"

Closes #36

See merge request pace/mobile/android/pace-cloud-sdk!30
  • Loading branch information
Martin Dinh committed Jan 15, 2021
2 parents fa2a824 + e8a1f33 commit 70e8a25
Show file tree
Hide file tree
Showing 38 changed files with 361 additions and 368 deletions.
161 changes: 89 additions & 72 deletions README.md

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,4 @@ dependencies {
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
implementation "androidx.preference:preference:$preference_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version"
}
14 changes: 4 additions & 10 deletions app/src/main/java/cloud/pace/sdk/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,15 @@ import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import cloud.pace.sdk.PACECloudSDK
import cloud.pace.sdk.appkit.AppKit
import cloud.pace.sdk.appkit.communication.AppCallbackImpl
import cloud.pace.sdk.appkit.model.App
import cloud.pace.sdk.appkit.model.AuthenticationMode
import cloud.pace.sdk.appkit.model.Configuration
import cloud.pace.sdk.idkit.FailedRetrievingSessionWhileAuthorizing
import cloud.pace.sdk.idkit.IDKit
import cloud.pace.sdk.idkit.OIDConfiguration
import cloud.pace.sdk.poikit.POIKit
import cloud.pace.sdk.utils.Environment
import cloud.pace.sdk.utils.Failure
import cloud.pace.sdk.utils.Success
import cloud.pace.sdk.utils.*
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
Expand Down Expand Up @@ -52,20 +49,17 @@ class MainActivity : AppCompatActivity() {
)
)

AppKit.setup(
PACECloudSDK.setup(
this, Configuration(
clientAppName = "PACECloudSDKExample",
clientAppVersion = BuildConfig.VERSION_NAME,
clientAppBuild = BuildConfig.VERSION_CODE.toString(),
apiKey = "YOUR_API_KEY",
isDarkTheme = false,
authenticationMode = AuthenticationMode.NATIVE,
environment = Environment.DEVELOPMENT
)
)

POIKit.setup(this, Environment.DEVELOPMENT, "YOUR_API_KEY")

if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
Expand Down Expand Up @@ -197,7 +191,7 @@ class MainActivity : AppCompatActivity() {
if (lastLocation == null || lastLocation.distanceTo(it) > APP_DISTANCE_THRESHOLD) {
AppKit.requestLocalApps { completion ->
if (completion is Success) {
AppKit.openApps(this, completion.result, false, root_layout, callback = object : AppCallbackImpl() {
AppKit.openApps(this, completion.result, root_layout, callback = object : AppCallbackImpl() {
override fun onOpen(app: App?) {
appUrl = app?.url
Toast.makeText(this@MainActivity, "Gas station ID = ${app?.gasStationId}", Toast.LENGTH_SHORT).show()
Expand Down
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ buildscript {
user = properties.get("user")
key = properties.get("key")

cloudsdk_version = "99578622"
gradle_version = "4.0.2"
kotlin_version = "1.4.10"
bintray_version = "1.8.5"
Expand Down
3 changes: 1 addition & 2 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])

implementation "car.pace:cloudsdk:$cloudsdk_version"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
Expand All @@ -66,6 +64,7 @@ dependencies {
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
implementation "androidx.preference:preference:$preference_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.biometric:biometric:$biometric_version"
implementation "androidx.browser:browser:$browser_version"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package cloud.pace.sdk.appkit

import androidx.test.runner.AndroidJUnit4
import cloud.pace.sdk.PACECloudSDK
import cloud.pace.sdk.appkit.app.api.UriManagerImpl
import cloud.pace.sdk.appkit.app.api.UriManagerImpl.Companion.PARAM_R
import cloud.pace.sdk.appkit.app.api.UriManagerImpl.Companion.PARAM_REFERENCES
import cloud.pace.sdk.appkit.model.Configuration
import cloud.pace.sdk.utils.Configuration
import cloud.pace.sdk.utils.Environment
import junit.framework.Assert.assertEquals
import org.junit.Before
Expand All @@ -18,7 +19,7 @@ class UriManagerTest {

@Before
fun init() {
AppKit.configuration = Configuration("", "", "", "", false, environment = Environment.DEVELOPMENT)
PACECloudSDK.configuration = Configuration("", "", "", "", environment = Environment.DEVELOPMENT)
}

@Test
Expand Down
61 changes: 61 additions & 0 deletions library/src/main/java/cloud/pace/sdk/PACECloudSDK.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cloud.pace.sdk

import android.content.Context
import cloud.pace.sdk.api.API
import cloud.pace.sdk.appkit.AppKit
import cloud.pace.sdk.appkit.persistence.SharedPreferencesModel
import cloud.pace.sdk.utils.CloudSDKKoinComponent
import cloud.pace.sdk.utils.Configuration
import cloud.pace.sdk.utils.KoinConfig
import org.koin.core.inject

object PACECloudSDK : CloudSDKKoinComponent {

private val sharedPreferencesModel: SharedPreferencesModel by inject()
internal lateinit var configuration: Configuration

/**
* Sets up [PACECloudSDK] with the passed [configuration].
* This needs to be called before any of its "Kits" can be used.
*
* @param context The context.
*/
fun setup(context: Context, configuration: Configuration) {
this.configuration = configuration

API.setupAPI("${configuration.environment.apiUrl}/poi/2020-4/", configuration.apiKey, emptyMap())
AppKit.locationAccuracy = configuration.locationAccuracy
KoinConfig.setupCloudSDK(context, configuration.environment, configuration.apiKey)
AppKit.updateUserAgent()
sharedPreferencesModel.deleteAllAppStates()
}

/**
* Replaces the list of optional [extensions] at the end of the user agent (separated with a space).
*/
fun setUserAgentExtensions(extensions: List<String>) {
if (::configuration.isInitialized) {
configuration.extensions = extensions
AppKit.updateUserAgent()
}
}

internal fun setLocationAccuracy(locationAccuracy: Int?) {
if (::configuration.isInitialized) {
configuration.locationAccuracy = locationAccuracy
}
}

internal fun setAccessToken(accessToken: String?) {
if (::configuration.isInitialized) {
configuration.accessToken = accessToken
AppKit.updateUserAgent()
}
}

internal fun resetAccessToken() {
if (::configuration.isInitialized) {
configuration.accessToken = null
}
}
}
89 changes: 23 additions & 66 deletions library/src/main/java/cloud/pace/sdk/appkit/AppKit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,93 +2,50 @@ package cloud.pace.sdk.appkit

import android.content.Context
import androidx.constraintlayout.widget.ConstraintLayout
import car.pace.cloudsdk.CloudSDK
import car.pace.cloudsdk.util.DeviceUtils
import cloud.pace.sdk.BuildConfig
import cloud.pace.sdk.PACECloudSDK
import cloud.pace.sdk.appkit.app.AppActivity
import cloud.pace.sdk.appkit.app.drawer.AppDrawer
import cloud.pace.sdk.appkit.communication.AppCallbackImpl
import cloud.pace.sdk.appkit.model.App
import cloud.pace.sdk.appkit.model.Car
import cloud.pace.sdk.appkit.model.Configuration
import cloud.pace.sdk.appkit.persistence.SharedPreferencesModel
import cloud.pace.sdk.utils.AppKitKoinComponent
import cloud.pace.sdk.utils.CloudSDKKoinComponent
import cloud.pace.sdk.utils.Completion
import cloud.pace.sdk.utils.KoinConfig
import cloud.pace.sdk.utils.DeviceUtils
import cloud.pace.sdk.utils.Theme
import org.koin.core.inject

object AppKit : AppKitKoinComponent {
object AppKit : CloudSDKKoinComponent {

private val sharedPreferencesModel: SharedPreferencesModel by inject()
private val appManager: AppManager by inject()

internal lateinit var configuration: Configuration
internal lateinit var userAgent: String

/**
* Sets up [AppKit] with the passed [configuration].
*
* @param context The context.
* Specifies whether the light or dark theme should be used for the apps.
*/
fun setup(context: Context, configuration: Configuration) {
this.configuration = configuration

CloudSDK.initialize(
context, CloudSDK.Configuration(
idBaseUrl = configuration.environment.idUrl,
apiBaseUrl = configuration.environment.apiUrl,
clientId = configuration.clientId ?: "",
clientVersion = configuration.clientAppVersion,
clientBuild = configuration.clientAppBuild,
isDarkTheme = configuration.isDarkTheme
)
)

KoinConfig.setupAppKit(context)
setUserAgent(configuration)
sharedPreferencesModel.deleteAllAppStates()
}

fun setThemeSetting(isDarkTheme: Boolean) {
if (::configuration.isInitialized) {
configuration.isDarkTheme = isDarkTheme
setUserAgent(configuration)
var theme: Theme = Theme.LIGHT
set(value) {
field = value
updateUserAgent()
}
}

fun setUserAgentExtensions(extensions: List<String>) {
if (::configuration.isInitialized) {
configuration.extensions = extensions
setUserAgent(configuration)
}
}

fun setLocationAccuracy(locationAccuracy: Int?) {
if (::configuration.isInitialized) {
configuration.locationAccuracy = locationAccuracy
}
}

internal fun setAccessToken(accessToken: String?) {
if (::configuration.isInitialized) {
configuration.accessToken = accessToken
setUserAgent(configuration)
}
}

internal fun resetAccessToken() {
if (::configuration.isInitialized) {
configuration.accessToken = null
/**
* Specifies the minimum location accuracy in meters to request location based apps.
*/
var locationAccuracy: Int? = null
set(value) {
field = value
PACECloudSDK.setLocationAccuracy(value)
}
}

private fun setUserAgent(config: Configuration) {
internal fun updateUserAgent() {
val config = PACECloudSDK.configuration
userAgent = listOf(
"${config.clientAppName}/${config.clientAppVersion}_${config.clientAppBuild}",
"(${DeviceUtils.getDeviceName()} Android/${DeviceUtils.getAndroidVersion()})",
"PWA-SDK/${BuildConfig.VERSION_NAME}",
if (config.clientId != null) "(clientid:${config.clientId};)" else "",
if (config.isDarkTheme) "PWASDK-Theme/Dark" else "PWASDK-Theme/Light",
if (theme == Theme.LIGHT) "PWASDK-Theme/Light" else "PWASDK-Theme/Dark",
"IdentityManagement/${config.authenticationMode.value}",
config.extensions.joinToString(" ")
).filter { it.isNotEmpty() }.joinToString(separator = " ")
Expand Down Expand Up @@ -170,7 +127,7 @@ object AppKit : AppKitKoinComponent {
* Clicking on the [AppDrawer] opens the [AppActivity] and shows the App.
*
* @param context Context which should be used to start the [AppActivity].
* @param isDarkBackground True, if the background of the [AppDrawer] should be dark, false otherwise.
* @param theme The [Theme] of the [AppDrawer].
* @param bottomMargin The margin with which the [AppDrawer]s should be drawn to the bottom edge.
* @param autoClose True if the [AppActivity] should be closed automatically when new apps are opened or no apps come back from the API, false otherwise.
* @param callback Via this callback the client app can subscribe to certain app events.
Expand All @@ -179,13 +136,13 @@ object AppKit : AppKitKoinComponent {
fun openApps(
context: Context,
apps: List<App>,
isDarkBackground: Boolean,
buttonContainer: ConstraintLayout,
theme: Theme = Theme.LIGHT,
bottomMargin: Float = 16f,
autoClose: Boolean = true,
callback: AppCallbackImpl? = null
) {
appManager.openApps(context, apps, isDarkBackground, buttonContainer, bottomMargin, autoClose, callback)
appManager.openApps(context, apps, buttonContainer, theme, bottomMargin, autoClose, callback)
}

/**
Expand Down
10 changes: 5 additions & 5 deletions library/src/main/java/cloud/pace/sdk/appkit/AppManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import java.net.MalformedURLException
import java.net.URL
import java.util.*

internal class AppManager : AppKitKoinComponent {
internal class AppManager : CloudSDKKoinComponent {

private val context: Context by inject()
private val appLocationManager: AppLocationManager by inject()
Expand Down Expand Up @@ -71,7 +71,7 @@ internal class AppManager : AppKitKoinComponent {
* @param completion Returns a list of [App]s on success or a [Throwable] on failure
*/
private fun getAppsByLocation(location: Location, completion: (Completion<List<App>>) -> Unit) {
appRepository.getLocationBasedApps(context, location.latitude, location.longitude, true) { result ->
appRepository.getLocationBasedApps(context, location.latitude, location.longitude) { result ->
result.onSuccess { apps ->
Log.d("Received ${apps.size} Apps: ${apps.map { it.url }}")

Expand Down Expand Up @@ -127,7 +127,7 @@ internal class AppManager : AppKitKoinComponent {
}

internal fun requestApps(completion: (Completion<List<App>>) -> Unit) {
appRepository.getAllApps(context, true) { result ->
appRepository.getAllApps(context) { result ->
result.onSuccess { completion(Success(it)) }
result.onFailure { completion(Failure(it)) }
}
Expand Down Expand Up @@ -176,7 +176,7 @@ internal class AppManager : AppKitKoinComponent {
context.startActivity(intent)
}

internal fun openApps(context: Context, apps: List<App>, isDarkBackground: Boolean, buttonContainer: ConstraintLayout, bottomMargin: Float, autoClose: Boolean, callback: AppCallbackImpl?) {
internal fun openApps(context: Context, apps: List<App>, buttonContainer: ConstraintLayout, theme: Theme, bottomMargin: Float, autoClose: Boolean, callback: AppCallbackImpl?) {
closeApps(buttonContainer)

var topAppDrawerId: Int? = null
Expand All @@ -186,7 +186,7 @@ internal class AppManager : AppKitKoinComponent {
appDrawer.id = View.generateViewId()
appDrawer.layoutParams = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.WRAP_CONTENT)

appDrawer.setApp(app, isDarkBackground) {
appDrawer.setApp(app, theme == Theme.DARK) {
openAppActivity(context, app, autoClose = autoClose, callback = callback)
}
appDrawer.expand()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import cloud.pace.sdk.R
import cloud.pace.sdk.appkit.app.webview.AppWebViewClient
import cloud.pace.sdk.appkit.communication.AppEventManager
import cloud.pace.sdk.appkit.communication.AppModel
import cloud.pace.sdk.utils.AppKitKoinComponent
import cloud.pace.sdk.utils.CloudSDKKoinComponent
import kotlinx.android.synthetic.main.fragment_app.*
import org.koin.android.ext.android.inject

class AppActivity : AppCompatActivity(), AppKitKoinComponent {
class AppActivity : AppCompatActivity(), CloudSDKKoinComponent {

private var backToFinish = true
private val eventManager: AppEventManager by inject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import androidx.browser.customtabs.CustomTabsIntent
import androidx.fragment.app.Fragment
import cloud.pace.sdk.R
import cloud.pace.sdk.appkit.app.webview.AppWebViewClient
import cloud.pace.sdk.utils.AppKitKoinComponent
import cloud.pace.sdk.utils.CloudSDKKoinComponent
import kotlinx.android.synthetic.main.fragment_app.*
import org.koin.android.viewmodel.ext.android.viewModel

class AppFragment : Fragment(), AppKitKoinComponent {
class AppFragment : Fragment(), CloudSDKKoinComponent {

private val viewModel: AppFragmentViewModel by viewModel()

Expand Down
Loading

0 comments on commit 70e8a25

Please sign in to comment.