-
-
Notifications
You must be signed in to change notification settings - Fork 957
/
MuzeiActivity.kt
244 lines (226 loc) · 11.1 KB
/
MuzeiActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
package com.google.android.apps.muzei
import android.app.Application
import android.content.ComponentName
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Resources
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.text.format.DateFormat
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.observe
import androidx.wear.ambient.AmbientModeSupport
import androidx.wear.widget.RoundedDrawable
import com.google.android.apps.muzei.datalayer.ActivateMuzeiIntentService
import com.google.android.apps.muzei.datalayer.DataLayerArtProvider
import com.google.android.apps.muzei.featuredart.BuildConfig.FEATURED_ART_AUTHORITY
import com.google.android.apps.muzei.render.ImageLoader
import com.google.android.apps.muzei.room.MuzeiDatabase
import com.google.android.apps.muzei.room.sendAction
import com.google.android.apps.muzei.sync.ProviderManager
import com.google.android.apps.muzei.util.coroutineScope
import com.google.android.apps.muzei.util.observeNonNull
import com.google.firebase.analytics.FirebaseAnalytics
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.nurik.roman.muzei.BuildConfig
import net.nurik.roman.muzei.BuildConfig.DATA_LAYER_AUTHORITY
import net.nurik.roman.muzei.R
import java.text.SimpleDateFormat
import java.util.Locale
class MuzeiViewModel(application: Application) : AndroidViewModel(application) {
val artworkLiveData = MuzeiDatabase.getInstance(application).artworkDao().currentArtwork
}
class MuzeiActivity : FragmentActivity(),
AmbientModeSupport.AmbientCallbackProvider {
companion object {
private const val FACTOR = 0.146467f // c = a * sqrt(2)
}
private val ambientCallback: AmbientModeSupport.AmbientCallback =
object : AmbientModeSupport.AmbientCallback() {
private val timeFormat12h = SimpleDateFormat("h:mm", Locale.getDefault())
private val timeFormat24h = SimpleDateFormat("H:mm", Locale.getDefault())
private var showImageOnExit = false
override fun onEnterAmbient(ambientDetails: Bundle?) {
showImageOnExit = imageView.isVisible
imageView.isVisible = false
timeView.isVisible = true
updateTime()
}
override fun onUpdateAmbient() {
updateTime()
}
fun updateTime() {
timeView.text = if (DateFormat.is24HourFormat(this@MuzeiActivity))
timeFormat24h.format(System.currentTimeMillis())
else
timeFormat12h.format(System.currentTimeMillis())
}
override fun onExitAmbient() {
imageView.isVisible = showImageOnExit
timeView.isVisible = false
}
}
private lateinit var ambientController: AmbientModeSupport.AmbientController
private lateinit var content: View
private lateinit var timeView: TextView
private lateinit var imageView: ImageView
private lateinit var titleView: TextView
private lateinit var bylineView: TextView
private lateinit var attributionView: TextView
private lateinit var nextArtwork: Button
private lateinit var openOnPhone: Button
private lateinit var providerView: Button
private lateinit var providerDescriptionView: TextView
private lateinit var providerSettingsView: Button
private val viewModel: MuzeiViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ambientController = AmbientModeSupport.attach(this)
FirebaseAnalytics.getInstance(this).setUserProperty("device_type", BuildConfig.DEVICE_TYPE)
setContentView(R.layout.muzei_activity)
content = findViewById(R.id.content)
timeView = findViewById(R.id.time)
imageView = findViewById(R.id.image)
titleView = findViewById(R.id.title)
bylineView = findViewById(R.id.byline)
attributionView = findViewById(R.id.attribution)
nextArtwork = findViewById(R.id.next_artwork)
openOnPhone = findViewById(R.id.open_on_phone)
providerView = findViewById(R.id.provider)
providerDescriptionView = findViewById(R.id.provider_description)
providerSettingsView = findViewById(R.id.provider_settings)
if (resources.configuration.isScreenRound) {
val inset = (FACTOR * Resources.getSystem().displayMetrics.widthPixels).toInt()
content.setPadding(inset, 0, inset, inset)
}
imageView.setOnClickListener {
startActivity(Intent(this@MuzeiActivity,
FullScreenActivity::class.java))
}
nextArtwork.setCompoundDrawablesRelative(RoundedDrawable().apply {
isClipEnabled = true
radius = resources.getDimensionPixelSize(R.dimen.art_detail_open_on_phone_radius)
backgroundColor = ContextCompat.getColor(this@MuzeiActivity,
R.color.theme_primary)
drawable = ContextCompat.getDrawable(this@MuzeiActivity,
R.drawable.ic_next_artwork)
bounds = Rect(0, 0, radius * 2, radius * 2)
}, null, null, null)
nextArtwork.setOnClickListener {
ProviderManager.getInstance(this).nextArtwork()
}
openOnPhone.setCompoundDrawablesRelative(RoundedDrawable().apply {
isClipEnabled = true
radius = resources.getDimensionPixelSize(R.dimen.art_detail_open_on_phone_radius)
backgroundColor = ContextCompat.getColor(this@MuzeiActivity,
R.color.theme_primary)
drawable = ContextCompat.getDrawable(this@MuzeiActivity,
R.drawable.open_on_phone_button)
bounds = Rect(0, 0, radius * 2, radius * 2)
}, null, null, null)
providerView.setOnClickListener {
startActivity(Intent(this@MuzeiActivity,
ChooseProviderActivity::class.java))
}
providerSettingsView.setCompoundDrawablesRelative(RoundedDrawable().apply {
isClipEnabled = true
radius = resources.getDimensionPixelSize(R.dimen.art_detail_open_on_phone_radius)
backgroundColor = ContextCompat.getColor(this@MuzeiActivity,
R.color.theme_primary)
drawable = ContextCompat.getDrawable(this@MuzeiActivity,
R.drawable.ic_provider_settings)
bounds = Rect(0, 0, radius * 2, radius * 2)
}, null, null, null)
viewModel.artworkLiveData.observeNonNull(this) { artwork ->
coroutineScope.launch(Dispatchers.Main) {
val image = ImageLoader.decode(
contentResolver, artwork.contentUri)
if (image != null) {
imageView.setImageDrawable(RoundedDrawable().apply {
isClipEnabled = true
radius = resources.getDimensionPixelSize(R.dimen.art_detail_image_radius)
drawable = BitmapDrawable(resources, image)
})
}
imageView.contentDescription = artwork.title
?: artwork.byline
?: artwork.attribution
imageView.isVisible = image != null && !ambientController.isAmbient
titleView.text = artwork.title
titleView.isVisible = !artwork.title.isNullOrBlank()
bylineView.text = artwork.byline
bylineView.isVisible = !artwork.byline.isNullOrBlank()
attributionView.text = artwork.attribution
attributionView.isVisible = !artwork.attribution.isNullOrBlank()
openOnPhone.setOnClickListener {
launch {
FirebaseAnalytics.getInstance(this@MuzeiActivity).logEvent(
FirebaseAnalytics.Event.SELECT_CONTENT, bundleOf(
FirebaseAnalytics.Param.ITEM_ID to DataLayerArtProvider.OPEN_ON_PHONE_ACTION,
FirebaseAnalytics.Param.ITEM_NAME to getString(R.string.common_open_on_phone),
FirebaseAnalytics.Param.ITEM_CATEGORY to "actions",
FirebaseAnalytics.Param.CONTENT_TYPE to "wear_activity"))
artwork.sendAction(this@MuzeiActivity,
DataLayerArtProvider.OPEN_ON_PHONE_ACTION)
}
}
openOnPhone.isVisible = artwork.providerAuthority == DATA_LAYER_AUTHORITY
}
}
ProviderManager.getInstance(this).observe(this) { provider ->
if (provider == null) {
val context = this@MuzeiActivity
GlobalScope.launch {
ProviderManager.select(context, FEATURED_ART_AUTHORITY)
ActivateMuzeiIntentService.checkForPhoneApp(context)
}
return@observe
}
nextArtwork.isVisible = provider.supportsNextArtwork
val pm = packageManager
val providerInfo = pm.resolveContentProvider(provider.authority,
PackageManager.GET_META_DATA)
if (providerInfo != null) {
val size = resources.getDimensionPixelSize(R.dimen.choose_provider_image_size)
val icon = providerInfo.loadIcon(pm)
icon.bounds = Rect(0, 0, size, size)
providerView.setCompoundDrawablesRelative(icon,
null, null, null)
providerView.text = providerInfo.loadLabel(pm)
val authority = providerInfo.authority
coroutineScope.launch(Dispatchers.Main) {
val description = ProviderManager.getDescription(this@MuzeiActivity, authority)
providerDescriptionView.isGone = description.isBlank()
providerDescriptionView.text = description
}
val settingsActivity = providerInfo.metaData?.getString("settingsActivity")?.run {
ComponentName(providerInfo.packageName, this)
}
providerSettingsView.isVisible = settingsActivity != null
providerSettingsView.setOnClickListener {
if (settingsActivity != null) {
startActivity(Intent().apply {
component = settingsActivity
})
}
}
}
}
}
override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
return ambientCallback
}
}