• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  *
17  */
18 
19 package com.android.healthconnect.controller.onboarding
20 
21 import android.app.Activity
22 import android.content.Context
23 import android.content.Intent
24 import android.os.Bundle
25 import android.view.LayoutInflater
26 import android.view.View
27 import android.view.WindowManager
28 import android.widget.Button
29 import android.widget.FrameLayout
30 import android.widget.TextView
31 import androidx.fragment.app.FragmentActivity
32 import com.android.healthconnect.controller.R
33 import com.android.healthconnect.controller.shared.Constants.ONBOARDING_SHOWN_PREF_KEY
34 import com.android.healthconnect.controller.shared.Constants.USER_ACTIVITY_TRACKER
35 import com.android.healthconnect.controller.utils.logging.HealthConnectLogger
36 import com.android.healthconnect.controller.utils.logging.OnboardingElement
37 import com.android.healthconnect.controller.utils.logging.PageName
38 import com.android.healthfitness.flags.AconfigFlagHelper.isPersonalHealthRecordEnabled
39 import com.android.settingslib.collapsingtoolbar.EdgeToEdgeUtils
40 import com.android.settingslib.widget.SettingsThemeHelper
41 import dagger.hilt.android.AndroidEntryPoint
42 import javax.inject.Inject
43 
44 /** Onboarding activity for Health Connect. */
45 @AndroidEntryPoint(FragmentActivity::class)
46 class OnboardingActivity : Hilt_OnboardingActivity() {
47 
48     /** Companion object for OnboardingActivity. */
49     companion object {
50         private const val TARGET_ACTIVITY_INTENT = "ONBOARDING_TARGET_ACTIVITY_INTENT"
51 
52         /** A utility function designed solely for testing purposes. */
disableOnboardingnull53         fun disableOnboarding(context: Context) {
54             val editor =
55                 context.getSharedPreferences(USER_ACTIVITY_TRACKER, Context.MODE_PRIVATE).edit()
56             editor.putBoolean(ONBOARDING_SHOWN_PREF_KEY, true)
57             editor.commit()
58         }
59 
shouldRedirectToOnboardingActivitynull60         fun shouldRedirectToOnboardingActivity(activity: Activity): Boolean {
61             val sharedPreference =
62                 activity.getSharedPreferences(USER_ACTIVITY_TRACKER, Context.MODE_PRIVATE)
63             val previouslyOpened = sharedPreference.getBoolean(ONBOARDING_SHOWN_PREF_KEY, false)
64             return !previouslyOpened
65         }
66 
createIntentnull67         fun createIntent(context: Context, targetIntent: Intent? = null): Intent {
68             val flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NO_ANIMATION
69 
70             return Intent(context, OnboardingActivity::class.java).apply {
71                 addFlags(flags)
72                 if (targetIntent != null) {
73                     putExtra(TARGET_ACTIVITY_INTENT, targetIntent)
74                 }
75             }
76         }
77     }
78 
79     @Inject lateinit var logger: HealthConnectLogger
80 
81     private var targetIntent: Intent? = null
82 
onCreatenull83     override fun onCreate(savedInstanceState: Bundle?) {
84         EdgeToEdgeUtils.enable(this)
85         if (SettingsThemeHelper.isExpressiveTheme(this)) {
86             setTheme(R.style.Theme_HealthConnect_Expressive)
87         }
88         super.onCreate(savedInstanceState)
89         // This flag ensures a non system app cannot show an overlay on Health Connect. b/313425281
90         window.addSystemFlags(
91             WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
92         )
93         if (intent.hasExtra(TARGET_ACTIVITY_INTENT)) {
94             targetIntent = intent.getParcelableExtra(TARGET_ACTIVITY_INTENT)
95         }
96 
97         logger.setPageId(PageName.ONBOARDING_PAGE)
98 
99         setupOnboardingScreen()
100     }
101 
onResumenull102     override fun onResume() {
103         super.onResume()
104         logger.logPageImpression()
105     }
106 
setupOnboardingScreennull107     private fun setupOnboardingScreen() {
108         setContentView(R.layout.onboarding_screen)
109 
110         val onboardingDescription = findViewById<TextView>(R.id.onboarding_description)
111         val withHealthConnectTitle =
112             findViewById<TextView>(R.id.onboarding_description_with_health_connect)
113         if (isPersonalHealthRecordEnabled()) {
114             onboardingDescription.setText(R.string.onboarding_description_health_records)
115             withHealthConnectTitle.visibility = View.VISIBLE
116             logger.logImpression(OnboardingElement.ONBOARDING_MESSAGE_WITH_PHR)
117         } else {
118             onboardingDescription.setText(R.string.onboarding_description)
119             withHealthConnectTitle.visibility = View.GONE
120         }
121 
122         setupButtonArea()
123     }
124 
setupButtonAreanull125     private fun setupButtonArea() {
126         val buttonArea = findViewById<FrameLayout>(R.id.button_area)
127         val buttonLayoutId =
128             if (SettingsThemeHelper.isExpressiveTheme(this)) {
129                 R.layout.widget_setup_bottom_button_bar_expressive
130             } else {
131                 R.layout.widget_setup_bottom_button_bar_legacy
132             }
133         buttonArea.addView(LayoutInflater.from(this).inflate(buttonLayoutId, buttonArea, false))
134 
135         val goBackButton = findViewById<Button>(R.id.secondary_button)
136         goBackButton.text = getString(R.string.onboarding_go_back_button_text)
137         val getStartedButton = findViewById<Button>(R.id.primary_button_full)
138         getStartedButton.text = getString(R.string.onboarding_get_started_button_text)
139         logger.logImpression(OnboardingElement.ONBOARDING_GO_BACK_BUTTON)
140         logger.logImpression(OnboardingElement.ONBOARDING_COMPLETED_BUTTON)
141 
142         goBackButton.setOnClickListener {
143             logger.logInteraction(OnboardingElement.ONBOARDING_GO_BACK_BUTTON)
144             setResult(Activity.RESULT_CANCELED)
145             finish()
146         }
147 
148         val sharedPreference = getSharedPreferences(USER_ACTIVITY_TRACKER, Context.MODE_PRIVATE)
149         getStartedButton.setOnClickListener {
150             logger.logInteraction(OnboardingElement.ONBOARDING_COMPLETED_BUTTON)
151             val editor = sharedPreference.edit()
152             editor.putBoolean(ONBOARDING_SHOWN_PREF_KEY, true)
153             editor.apply()
154             if (targetIntent == null) {
155                 setResult(Activity.RESULT_OK)
156             } else {
157                 startActivity(targetIntent)
158             }
159             finish()
160         }
161     }
162 }
163