Initial commit of the Quest build (#2106)

* Initial commit of the Quest build

* Tweak readme
This commit is contained in:
Daniel Shokouhi 2022-01-04 16:32:45 -08:00 committed by GitHub
parent e2d8e51792
commit eede556a77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 323 additions and 29 deletions

View File

@ -21,6 +21,7 @@ runs:
run: |
cp .github/mock-google-services.json app/src/debug/google-services.json
cp .github/mock-google-services.json app/src/minimal/google-services.json
cp .github/mock-google-services.json app/src/quest/google-services.json
- name: Inflate release_keystore.keystore
shell: bash

View File

@ -57,6 +57,32 @@
"current_key": "current_key"
}
]
},
{
"client_info": {
"mobilesdk_app_id": "mobilesdk_app_id",
"android_client_info": {
"package_name": "io.homeassistant.companion.android.quest"
}
},
"api_key": [
{
"current_key": "current_key"
}
]
},
{
"client_info": {
"mobilesdk_app_id": "mobilesdk_app_id",
"android_client_info": {
"package_name": "io.homeassistant.companion.android.quest.debug"
}
},
"api_key": [
{
"current_key": "current_key"
}
]
}
],
"configuration_version": "1"

View File

@ -92,6 +92,16 @@ jobs:
asset_name: home-assistant-minimal-${{steps.rel_number.outputs.version}}.apk
asset_content_type: application/zip
- name: Upload Quest APK
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./app/build/outputs/apk/quest/release/app-quest-release.apk
asset_name: home-assistant-quest-${{steps.rel_number.outputs.version}}.apk
asset_content_type: application/zip
- name: Upload Wear APK
uses: actions/upload-release-asset@v1
env:

View File

@ -91,6 +91,16 @@ jobs:
asset_name: home-assistant-minimal-${{steps.rel_number.outputs.version}}.apk
asset_content_type: application/zip
- name: Upload Quest APK
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./app/build/outputs/apk/quest/release/app-quest-release.apk
asset_name: home-assistant-quest-${{steps.rel_number.outputs.version}}.apk
asset_content_type: application/zip
- name: Upload Wear APK
uses: actions/upload-release-asset@v1
env:

View File

@ -11,11 +11,13 @@ If you are looking for documentation around the companion applications check out
- Create a Firebase project at [Firebase Console](https://console.firebase.google.com)
- Create four Android apps, with following package names
- Create six Android apps, with following package names
- `io.homeassistant.companion.android`
- `io.homeassistant.companion.android.debug`
- `io.homeassistant.companion.android.minimal`
- `io.homeassistant.companion.android.minimal.debug`
- `io.homeassistant.companion.android.quest`
- `io.homeassistant.companion.android.quest.debug`
- Now download the `google-services.json` file and put it in the _home-assistant-Android/app_ folder. This file contains the configuration of the whole project (all the four applications).
@ -55,7 +57,7 @@ homeAssistantAndroidRateLimitUrl=https://mydomain.cloudfunctions.net/checkRateLi
## App Flavors
The Android app has both a full flavor that uses Google Play Services to offer features like location tracking and notifications. There is also a minimal flavor that does not require Google Play Services and can be found in the releases section. The minimal flavor does not have location tracking or notifications.
The Android app has both a full flavor that uses Google Play Services to offer features like location tracking and notifications. There is also a minimal flavor that does not require Google Play Services and can be found in the releases section. The minimal flavor does not have location tracking or notifications. The quest flavor is identical to the minimal flavor with the exception of changes required for the device.
## Testing Dev Releases

View File

@ -84,6 +84,11 @@ android {
applicationIdSuffix = ""
versionNameSuffix = "-full"
}
create("quest") {
applicationIdSuffix = ".quest"
versionNameSuffix = "-quest"
minSdk = 23
}
// Generate a list of application ids into BuildConfig
val values = productFlavors.joinToString {
@ -97,6 +102,9 @@ android {
register("minimal") {
enabled.set(false)
}
register("quest") {
enabled.set(false)
}
}
testOptions {

View File

@ -100,7 +100,7 @@ class LaunchActivity : AppCompatActivity(), LaunchView {
val deviceName = intent.getStringExtra("DeviceName").toString()
val deviceTrackingEnabled = intent.getBooleanExtra("LocationTracking", false)
val messagingToken = getMessagingToken()
if (messagingToken.isNullOrBlank()) {
if (messagingToken.isNullOrBlank() && BuildConfig.FLAVOR == "full") {
AlertDialog.Builder(this@LaunchActivity)
.setTitle(commonR.string.firebase_error_title)
.setMessage(commonR.string.firebase_error_message)

View File

@ -141,6 +141,7 @@ class SettingsFragment constructor(
return@setOnPreferenceClickListener true
}
findPreference<PreferenceCategory>("widgets")?.isVisible = BuildConfig.FLAVOR != "quest"
findPreference<Preference>("manage_widgets")?.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
@ -150,31 +151,33 @@ class SettingsFragment constructor(
return@setOnPreferenceClickListener true
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
findPreference<PreferenceCategory>("shortcuts")?.let {
it.isVisible = true
if (BuildConfig.FLAVOR != "quest") {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
findPreference<PreferenceCategory>("shortcuts")?.let {
it.isVisible = true
}
findPreference<Preference>("manage_shortcuts")?.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
.replace(R.id.content, ManageShortcutsSettingsFragment::class.java, null)
.addToBackStack(getString(commonR.string.shortcuts))
.commit()
return@setOnPreferenceClickListener true
}
}
findPreference<Preference>("manage_shortcuts")?.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
.replace(R.id.content, ManageShortcutsSettingsFragment::class.java, null)
.addToBackStack(getString(commonR.string.shortcuts))
.commit()
return@setOnPreferenceClickListener true
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
findPreference<PreferenceCategory>("quick_settings")?.let {
it.isVisible = true
}
findPreference<Preference>("manage_tiles")?.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
.replace(R.id.content, ManageTilesFragment::class.java, null)
.addToBackStack(getString(commonR.string.tiles))
.commit()
return@setOnPreferenceClickListener true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
findPreference<PreferenceCategory>("quick_settings")?.let {
it.isVisible = true
}
findPreference<Preference>("manage_tiles")?.setOnPreferenceClickListener {
parentFragmentManager
.beginTransaction()
.replace(R.id.content, ManageTilesFragment::class.java, null)
.addToBackStack(getString(commonR.string.tiles))
.commit()
return@setOnPreferenceClickListener true
}
}
}
@ -217,7 +220,7 @@ class SettingsFragment constructor(
}
}
findPreference<SwitchPreference>("crash_reporting")?.let {
it.isVisible = true
it.isVisible = BuildConfig.FLAVOR == "full"
it.setOnPreferenceChangeListener { _, newValue ->
val checked = newValue as Boolean
@ -228,7 +231,7 @@ class SettingsFragment constructor(
val pm = requireContext().packageManager
val hasWearApp = pm.getLaunchIntentForPackage("com.google.android.wearable.app")
val hasSamsungApp = pm.getLaunchIntentForPackage("com.samsung.android.app.watchmanager")
findPreference<PreferenceCategory>("wear_category")?.isVisible = hasWearApp != null || hasSamsungApp != null
findPreference<PreferenceCategory>("wear_category")?.isVisible = BuildConfig.FLAVOR == "full" && (hasWearApp != null || hasSamsungApp != null)
findPreference<Preference>("wear_settings")?.setOnPreferenceClickListener {
startActivity(SettingsWearActivity.newInstance(requireContext()))
return@setOnPreferenceClickListener true
@ -238,7 +241,7 @@ class SettingsFragment constructor(
findPreference<Preference>("changelog")?.let {
val link = if (BuildConfig.VERSION_NAME.startsWith("LOCAL"))
"https://github.com/home-assistant/android/releases"
else "https://github.com/home-assistant/android/releases/tag/${BuildConfig.VERSION_NAME.replace("-full", "").replace("-minimal", "")}"
else "https://github.com/home-assistant/android/releases/tag/${BuildConfig.VERSION_NAME.replace("-full", "").replace("-minimal", "").replace("-quest", "")}"
it.summary = link
it.intent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:compileSdkVersion="29"
android:installLocation="auto"
package="io.homeassistant.companion.android">
<uses-feature android:name="android.hardware.vr.headtracking" android:required="true" android:version="1"
tools:targetApi="n" />
<application android:allowBackup="false"
tools:replace="android:allowBackup"
android:icon="@mipmap/ic_launcher">
<activity android:name=".launch.LaunchActivity" android:excludeFromRecents="true" />
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2"/>
</application>
</manifest>

View File

@ -0,0 +1,7 @@
package io.homeassistant.companion.android
import android.content.Context
fun initCrashReporting(context: Context, enabled: Boolean) {
// Noop
}

View File

@ -0,0 +1,29 @@
package io.homeassistant.companion.android.launch
import android.util.Log
import io.homeassistant.companion.android.BuildConfig
import io.homeassistant.companion.android.common.data.authentication.AuthenticationRepository
import io.homeassistant.companion.android.common.data.integration.DeviceRegistration
import io.homeassistant.companion.android.common.data.integration.IntegrationRepository
import kotlinx.coroutines.launch
import javax.inject.Inject
class LaunchPresenterImpl @Inject constructor(
view: LaunchView,
authenticationUseCase: AuthenticationRepository,
integrationUseCase: IntegrationRepository
) : LaunchPresenterBase(view, authenticationUseCase, integrationUseCase) {
override fun resyncRegistration() {
mainScope.launch {
try {
integrationUseCase.updateRegistration(
DeviceRegistration(
"${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})"
)
)
} catch (e: Exception) {
Log.e(TAG, "Issue updating Registration", e)
}
}
}
}

View File

@ -0,0 +1,5 @@
package io.homeassistant.companion.android.onboarding
suspend fun getMessagingToken(): String {
return ""
}

View File

@ -0,0 +1,32 @@
package io.homeassistant.companion.android.sensors
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import io.homeassistant.companion.android.common.sensors.SensorManager
import io.homeassistant.companion.android.common.R as commonR
class ActivitySensorManager : BroadcastReceiver(), SensorManager {
override fun onReceive(context: Context, intent: Intent) {
// Noop
}
override val enabledByDefault: Boolean
get() = false
override val name: Int
get() = commonR.string.sensor_name_activity
override fun getAvailableSensors(context: Context): List<SensorManager.BasicSensor> {
return listOf()
}
override fun requiredPermissions(sensorId: String): Array<String> {
// Noop
return emptyArray()
}
override fun requestSensorUpdate(context: Context) {
// Noop
}
}

View File

@ -0,0 +1,35 @@
package io.homeassistant.companion.android.sensors
import android.content.Context
import io.homeassistant.companion.android.common.sensors.SensorManager
import io.homeassistant.companion.android.common.R as commonR
class GeocodeSensorManager : SensorManager {
companion object {
private const val TAG = "GeocodeSM"
val geocodedLocation = SensorManager.BasicSensor(
"geocoded_location",
"sensor",
commonR.string.basic_sensor_name_geolocation,
commonR.string.sensor_description_geocoded_location
)
}
override val enabledByDefault: Boolean
get() = false
override val name: Int
get() = commonR.string.sensor_name_geolocation
override fun getAvailableSensors(context: Context): List<SensorManager.BasicSensor> {
return listOf()
}
override fun requiredPermissions(sensorId: String): Array<String> {
return emptyArray()
}
override fun requestSensorUpdate(context: Context) {
// No op
}
}

View File

@ -0,0 +1,65 @@
package io.homeassistant.companion.android.sensors
import android.content.Context
import android.content.Intent
import io.homeassistant.companion.android.common.sensors.LocationSensorManagerBase
import io.homeassistant.companion.android.common.sensors.SensorManager
import io.homeassistant.companion.android.common.R as commonR
class LocationSensorManager : LocationSensorManagerBase(), SensorManager {
companion object {
const val MINIMUM_ACCURACY = 200
const val ACTION_REQUEST_LOCATION_UPDATES =
"io.homeassistant.companion.android.background.REQUEST_UPDATES"
const val ACTION_REQUEST_ACCURATE_LOCATION_UPDATE =
"io.homeassistant.companion.android.background.REQUEST_ACCURATE_UPDATE"
const val ACTION_PROCESS_LOCATION =
"io.homeassistant.companion.android.background.PROCESS_UPDATES"
const val ACTION_PROCESS_GEO =
"io.homeassistant.companion.android.background.PROCESS_GEOFENCE"
val backgroundLocation = SensorManager.BasicSensor(
"location_background",
"",
commonR.string.basic_sensor_name_location_background,
commonR.string.sensor_description_location_background
)
val zoneLocation = SensorManager.BasicSensor(
"zone_background",
"",
commonR.string.basic_sensor_name_location_zone,
commonR.string.sensor_description_location_zone
)
val singleAccurateLocation = SensorManager.BasicSensor(
"accurate_location",
"",
commonR.string.basic_sensor_name_location_accurate,
commonR.string.sensor_description_location_accurate
)
internal const val TAG = "LocBroadcastReceiver"
}
override fun onReceive(context: Context, intent: Intent) {
// Noop
}
override val enabledByDefault: Boolean
get() = false
override val name: Int
get() = commonR.string.sensor_name_location
override fun getAvailableSensors(context: Context): List<SensorManager.BasicSensor> {
return listOf()
}
override fun requiredPermissions(sensorId: String): Array<String> {
// Noop
return emptyArray()
}
override fun requestSensorUpdate(context: Context) {
// Noop
}
}

View File

@ -0,0 +1,22 @@
package io.homeassistant.companion.android.settings.wear
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.wearable.CapabilityClient
import com.google.android.gms.wearable.CapabilityInfo
class SettingsWearActivity : AppCompatActivity(), CapabilityClient.OnCapabilityChangedListener {
override fun onCapabilityChanged(capabilityInfo: CapabilityInfo) {
// No op
}
companion object {
private const val TAG = "SettingsWearAct"
fun newInstance(context: Context): Intent {
return Intent(context, SettingsWearActivity::class.java)
}
}
}

View File

@ -0,0 +1,22 @@
package io.homeassistant.companion.android.settings
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.wearable.DataClient
import com.google.android.gms.wearable.DataEventBuffer
class SettingsWearMainView : AppCompatActivity(), DataClient.OnDataChangedListener {
companion object {
private const val TAG = "SettingsWearMainView"
fun newInstance(context: Context): Intent {
return Intent(context, SettingsWearMainView::class.java)
}
}
override fun onDataChanged(dataEvents: DataEventBuffer) {
// No op
}
}