From 71848294bc8b4409264edbcb9e05b3a925a5bf89 Mon Sep 17 00:00:00 2001 From: Kevin Lind <40409666+kevinlind@users.noreply.github.com> Date: Thu, 25 Mar 2021 12:23:54 -0700 Subject: [PATCH] Add sample app (#20) * Use correct direct Identity data store name * Override toString in IdentityMap and IdentityItem * Add Kotlin test app for IdentityEdge * Add fragment for starting an Assurance session * Remove unused test files from sample app. * Add implementations for send event and reset identities buttons. * Add Application class to initialize SDK and extensions * Add network security config to AndroidManifest * Comment out call to resetIdentities as API in Core is not yet released * Remove Java app * Rename 'appkt' to 'app' and move files to 'code/app' * Remove launch environment ID * Rename test app package from 'appkt' to 'app' * fix IdentityMap.toString to handle case where map is empty. * Use correct AuthenticatedState.loggedOut string * Save custom identifier UI entries and update UI with saved values when page is viewed. * Remove copyright from non-source files (Manifest, layouts, drawables, etc). * Make StringBuilder final in IdentityMap.toString() --- code/app/build.gradle | 37 ++++- code/app/src/main/AndroidManifest.xml | 28 +--- .../identity/app/EdgeIdentityApplication.kt | 40 +++++ .../edge/identity/app/MainActivity.kt | 57 +++++++ .../identity/app/model/SharedViewModel.kt | 148 +++++++++++++++++ .../edge/identity/app/ui/AssuranceFragment.kt | 41 +++++ .../identity/app/ui/CustomIdentityFragment.kt | 94 +++++++++++ .../identity/app/ui/GetIdentityFragment.kt | 100 +++++++++++ .../app/ui/MultipleIdentityFragment.kt | 118 +++++++++++++ .../mobile/testApp/MainActivity.java | 31 ---- .../mobile/testApp/TestApplication.java | 71 -------- .../res/drawable-anydpi/ic_menu_assurance.xml | 11 ++ .../res/drawable-hdpi/ic_menu_assurance.png | Bin 0 -> 268 bytes .../res/drawable-mdpi/ic_menu_assurance.png | Bin 0 -> 204 bytes .../main/res/drawable-v21/ic_menu_camera.xml | 12 ++ .../main/res/drawable-v21/ic_menu_gallery.xml | 9 + .../res/drawable-v21/ic_menu_slideshow.xml | 9 + .../drawable-v24/ic_launcher_foreground.xml | 8 +- .../res/drawable-xhdpi/ic_menu_assurance.png | Bin 0 -> 326 bytes .../res/drawable-xxhdpi/ic_menu_assurance.png | Bin 0 -> 411 bytes code/app/src/main/res/drawable/border.xml | 7 + .../res/drawable/ic_launcher_background.xml | 133 +++++++-------- .../src/main/res/drawable/side_nav_bar.xml | 9 + .../app/src/main/res/layout/activity_main.xml | 27 +-- code/app/src/main/res/layout/app_bar_main.xml | 25 +++ code/app/src/main/res/layout/content_main.xml | 20 +++ .../main/res/layout/fragment_assurance.xml | 45 +++++ .../res/layout/fragment_custom_identity.xml | 156 ++++++++++++++++++ .../main/res/layout/fragment_get_identity.xml | 92 +++++++++++ .../res/layout/fragment_multiple_identity.xml | 107 ++++++++++++ .../src/main/res/layout/nav_header_main.xml | 36 ++++ .../main/res/menu/activity_main_drawer.xml | 24 +++ code/app/src/main/res/menu/main.xml | 9 + .../main/res/navigation/mobile_navigation.xml | 31 ++++ code/app/src/main/res/values/colors.xml | 1 + code/app/src/main/res/values/dimens.xml | 9 + code/app/src/main/res/values/drawables.xml | 9 + code/app/src/main/res/values/strings.xml | 35 +++- code/app/src/main/res/values/styles.xml | 10 ++ code/build.gradle | 4 + .../edge/identity/IdentityConstants.java | 2 +- .../mobile/edge/identity/IdentityItem.java | 9 + .../mobile/edge/identity/IdentityMap.java | 24 +++ code/settings.gradle | 2 +- 44 files changed, 1433 insertions(+), 207 deletions(-) create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/EdgeIdentityApplication.kt create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/MainActivity.kt create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/model/SharedViewModel.kt create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/AssuranceFragment.kt create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/CustomIdentityFragment.kt create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/GetIdentityFragment.kt create mode 100644 code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/MultipleIdentityFragment.kt delete mode 100644 code/app/src/main/java/com/adobe/marketing/mobile/testApp/MainActivity.java delete mode 100644 code/app/src/main/java/com/adobe/marketing/mobile/testApp/TestApplication.java create mode 100644 code/app/src/main/res/drawable-anydpi/ic_menu_assurance.xml create mode 100644 code/app/src/main/res/drawable-hdpi/ic_menu_assurance.png create mode 100644 code/app/src/main/res/drawable-mdpi/ic_menu_assurance.png create mode 100644 code/app/src/main/res/drawable-v21/ic_menu_camera.xml create mode 100644 code/app/src/main/res/drawable-v21/ic_menu_gallery.xml create mode 100644 code/app/src/main/res/drawable-v21/ic_menu_slideshow.xml create mode 100644 code/app/src/main/res/drawable-xhdpi/ic_menu_assurance.png create mode 100644 code/app/src/main/res/drawable-xxhdpi/ic_menu_assurance.png create mode 100644 code/app/src/main/res/drawable/border.xml create mode 100644 code/app/src/main/res/drawable/side_nav_bar.xml create mode 100644 code/app/src/main/res/layout/app_bar_main.xml create mode 100644 code/app/src/main/res/layout/content_main.xml create mode 100644 code/app/src/main/res/layout/fragment_assurance.xml create mode 100644 code/app/src/main/res/layout/fragment_custom_identity.xml create mode 100644 code/app/src/main/res/layout/fragment_get_identity.xml create mode 100644 code/app/src/main/res/layout/fragment_multiple_identity.xml create mode 100644 code/app/src/main/res/layout/nav_header_main.xml create mode 100644 code/app/src/main/res/menu/activity_main_drawer.xml create mode 100644 code/app/src/main/res/menu/main.xml create mode 100644 code/app/src/main/res/navigation/mobile_navigation.xml create mode 100644 code/app/src/main/res/values/dimens.xml create mode 100644 code/app/src/main/res/values/drawables.xml diff --git a/code/app/build.gradle b/code/app/build.gradle index cdb6e30e..e88e1780 100644 --- a/code/app/build.gradle +++ b/code/app/build.gradle @@ -1,15 +1,30 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you 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 REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 30 buildToolsVersion "30.0.2" defaultConfig { - applicationId "com.adobe.marketing.mobile.identitytestapp" + applicationId "com.adobe.marketing.edge.identity.app" minSdkVersion 19 targetSdkVersion 30 versionCode 1 versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -18,16 +33,32 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.navigation:navigation-fragment:2.3.3' + implementation 'androidx.navigation:navigation-ui:2.3.3' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.3.3' + implementation 'androidx.navigation:navigation-ui-ktx:2.3.3' implementation project(':edgeidentity') implementation 'com.adobe.marketing.mobile:core:1+' - implementation 'com.adobe.marketing.mobile:signal:1+' + implementation 'com.adobe.marketing.mobile:identity:1+' implementation 'com.adobe.marketing.mobile:edge:1+' implementation 'com.adobe.marketing.mobile:assurance:1+' -} \ No newline at end of file +} diff --git a/code/app/src/main/AndroidManifest.xml b/code/app/src/main/AndroidManifest.xml index 5bb87b87..c2c09393 100644 --- a/code/app/src/main/AndroidManifest.xml +++ b/code/app/src/main/AndroidManifest.xml @@ -1,37 +1,27 @@ + + package="com.adobe.marketing.edge.identity.app"> - + android:networkSecurityConfig="@xml/network_security_config" + android:theme="@style/AppTheme"> + - - - - - - - - - - - - \ No newline at end of file diff --git a/code/app/src/main/java/com/adobe/marketing/edge/identity/app/EdgeIdentityApplication.kt b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/EdgeIdentityApplication.kt new file mode 100644 index 00000000..bfd92c45 --- /dev/null +++ b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/EdgeIdentityApplication.kt @@ -0,0 +1,40 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you 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 REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +package com.adobe.marketing.edge.identity.app + +import android.app.Application +import com.adobe.marketing.mobile.Assurance +import com.adobe.marketing.mobile.Edge +import com.adobe.marketing.mobile.LoggingMode +import com.adobe.marketing.mobile.MobileCore +import com.adobe.marketing.mobile.edge.identity.Identity + +class EdgeIdentityApplication : Application() { + // Add your Launch Environment ID to configure the SDK from your Launch property + private var LAUNCH_ENVIRONMENT_ID: String = "" + + override fun onCreate() { + super.onCreate() + + // register AEP SDK extensions + MobileCore.setApplication(this) + MobileCore.setLogLevel(LoggingMode.VERBOSE) + + Identity.registerExtension() + Edge.registerExtension() + Assurance.registerExtension() + + MobileCore.start { + MobileCore.configureWithAppID(LAUNCH_ENVIRONMENT_ID) + } + } +} \ No newline at end of file diff --git a/code/app/src/main/java/com/adobe/marketing/edge/identity/app/MainActivity.kt b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/MainActivity.kt new file mode 100644 index 00000000..65addbca --- /dev/null +++ b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/MainActivity.kt @@ -0,0 +1,57 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you 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 REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +package com.adobe.marketing.edge.identity.app + +import android.os.Bundle +import android.view.Menu +import com.google.android.material.navigation.NavigationView +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import androidx.navigation.ui.setupActionBarWithNavController +import androidx.navigation.ui.setupWithNavController +import androidx.drawerlayout.widget.DrawerLayout +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.Toolbar + +class MainActivity : AppCompatActivity() { + + private lateinit var appBarConfiguration: AppBarConfiguration + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + val toolbar: Toolbar = findViewById(R.id.toolbar) + setSupportActionBar(toolbar) + + val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) + val navView: NavigationView = findViewById(R.id.nav_view) + val navController = findNavController(R.id.nav_host_fragment) + // Passing each menu ID as a set of Ids because each + // menu should be considered as top level destinations. + appBarConfiguration = AppBarConfiguration(setOf( + R.id.nav_get_identity, R.id.nav_custom_identity, R.id.nav_multiple_identity, R.id.nav_assurance), drawerLayout) + setupActionBarWithNavController(navController, appBarConfiguration) + navView.setupWithNavController(navController) + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + // Inflate the menu; this adds items to the action bar if it is present. + menuInflater.inflate(R.menu.main, menu) + return true + } + + override fun onSupportNavigateUp(): Boolean { + val navController = findNavController(R.id.nav_host_fragment) + return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() + } +} diff --git a/code/app/src/main/java/com/adobe/marketing/edge/identity/app/model/SharedViewModel.kt b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/model/SharedViewModel.kt new file mode 100644 index 00000000..b3432bf8 --- /dev/null +++ b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/model/SharedViewModel.kt @@ -0,0 +1,148 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you 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 REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +package com.adobe.marketing.edge.identity.app.model + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.adobe.marketing.mobile.edge.identity.AuthenticatedState + +class SharedViewModel : ViewModel() { + companion object { + const val REGISTER_IDENTITY_STRING = "Register Identity" + const val REGISTER_EDGE_IDENTITY_STRING = "Register Edge Identity" + const val IDENTITY_IS_REGISTERED_STRING = "Identity is registered" + const val EDGE_IDENTITY_IS_REGISTERED_STRING = "Edge Identity is registered" + } + + // Models for Get Identities View + + private val _ecidText = MutableLiveData("") + val ecidText: LiveData = _ecidText + + private val _ecidLegacyText = MutableLiveData("") + val ecidLegacyText: LiveData = _ecidLegacyText + + private val _identitiesText = MutableLiveData("") + val identitiesText: LiveData = _identitiesText + + fun setEcidValue(value: String) { + _ecidText.value = value + } + + fun setEcidLegacyValue(value: String) { + _ecidLegacyText.value = value + } + + fun setIdentitiesValue(value: String) { + _identitiesText.value = value + } + + // Models for Update Identities View + + private val _identifier = MutableLiveData("") + val identifier: LiveData = _identifier + + private val _namespace = MutableLiveData("") + val namespace: LiveData = _namespace + + private val _isPrimary = MutableLiveData(false) + val isPrimary: LiveData = _isPrimary + + private val _authenticatedState = MutableLiveData(AuthenticatedState.AMBIGUOUS) + val authenticatedState: LiveData = _authenticatedState + + private val _authenticatedStateId = MutableLiveData(null) + val authenticatedStateId: LiveData = _authenticatedStateId + + fun setIdentifier(value: String) { + if (_identifier.value == value) { + return + } + _identifier.value = value + } + + fun setNamespace(value: String) { + if (_namespace.value == value) { + return + } + _namespace.value = value + } + + fun setIsPrimary(value: Boolean) { + if (_isPrimary.value == value) { + return + } + _isPrimary.value = value + } + + fun setAuthenticatedState(value: AuthenticatedState) { + if (_authenticatedState.value == value) { + return + } + _authenticatedState.value = value + } + + fun setAuthenticatedStateId(value: Int) { + if (_authenticatedStateId.value == value) { + return + } + _authenticatedStateId.value = value + } + + // Models for Multiple Identities View + + private val _isEdgeIdentityRegistered = MutableLiveData(true) + val isEdgeIdentityRegistered: LiveData = _isEdgeIdentityRegistered + + private val _edgeIdentityRegisteredText = MutableLiveData().apply { + value = if (_isEdgeIdentityRegistered.value == true) { + EDGE_IDENTITY_IS_REGISTERED_STRING + } else { + REGISTER_EDGE_IDENTITY_STRING + } + } + val edgeIdentityRegisteredText: LiveData = _edgeIdentityRegisteredText + + private val _isDirectIdentityRegistered = MutableLiveData(false) + val isDirectIdentityRegistered: LiveData = _isDirectIdentityRegistered + + private val _directIdentityRegisteredText = MutableLiveData().apply { + value = if (_isDirectIdentityRegistered.value == true) { + IDENTITY_IS_REGISTERED_STRING + } else { + REGISTER_IDENTITY_STRING + } + } + val directIdentityRegisteredText: LiveData = _directIdentityRegisteredText + + + fun toggleEdgeIdentityRegistration() { + if (_isEdgeIdentityRegistered.value == true) { + _isEdgeIdentityRegistered.value = false + _edgeIdentityRegisteredText.value = REGISTER_EDGE_IDENTITY_STRING + } else { + _isEdgeIdentityRegistered.value = true + _edgeIdentityRegisteredText.value = EDGE_IDENTITY_IS_REGISTERED_STRING + } + } + + fun toggleDirectIdentityRegistration() { + if (_isDirectIdentityRegistered.value == true) { + _isDirectIdentityRegistered.value = false + _directIdentityRegisteredText.value = REGISTER_IDENTITY_STRING + } else { + _isDirectIdentityRegistered.value = true + _directIdentityRegisteredText.value = IDENTITY_IS_REGISTERED_STRING + } + } +} \ No newline at end of file diff --git a/code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/AssuranceFragment.kt b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/AssuranceFragment.kt new file mode 100644 index 00000000..0fa690db --- /dev/null +++ b/code/app/src/main/java/com/adobe/marketing/edge/identity/app/ui/AssuranceFragment.kt @@ -0,0 +1,41 @@ +/* + Copyright 2021 Adobe. All rights reserved. + This file is licensed to you 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 REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +package com.adobe.marketing.edge.identity.app.ui + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.EditText +import androidx.fragment.app.Fragment +import com.adobe.marketing.edge.identity.app.R +import com.adobe.marketing.mobile.Assurance + +class AssuranceFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val root = inflater.inflate(R.layout.fragment_assurance, container, false) + + root.findViewById