mirror of
https://github.com/home-assistant/android
synced 2024-07-08 20:05:52 +00:00
Initial commit of the Quest build (#2106)
* Initial commit of the Quest build * Tweak readme
This commit is contained in:
parent
e2d8e51792
commit
eede556a77
1
.github/actions/inflate-secrets/action.yml
vendored
1
.github/actions/inflate-secrets/action.yml
vendored
|
@ -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
|
||||
|
|
26
.github/mock-google-services.json
vendored
26
.github/mock-google-services.json
vendored
|
@ -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"
|
||||
|
|
10
.github/workflows/beta.yml
vendored
10
.github/workflows/beta.yml
vendored
|
@ -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:
|
||||
|
|
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
17
app/src/quest/AndroidManifest.xml
Executable file
17
app/src/quest/AndroidManifest.xml
Executable 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>
|
7
app/src/quest/java/io/homeassistant/companion/android/CrashHandling.kt
Executable file
7
app/src/quest/java/io/homeassistant/companion/android/CrashHandling.kt
Executable file
|
@ -0,0 +1,7 @@
|
|||
package io.homeassistant.companion.android
|
||||
|
||||
import android.content.Context
|
||||
|
||||
fun initCrashReporting(context: Context, enabled: Boolean) {
|
||||
// Noop
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package io.homeassistant.companion.android.onboarding
|
||||
|
||||
suspend fun getMessagingToken(): String {
|
||||
return ""
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user