owenclave / app/src/main/java/io/nekohasekai/sagernet/bg/TileService.kt

github - dev - back to tree - upstream
/******************************************************************************* * * * Copyright (C) 2017 by Max Lv * * Copyright (C) 2017 by Mygod Studio * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * *******************************************************************************/ package io.nekohasekai.sagernet.bg import android.app.KeyguardManager import android.graphics.drawable.Icon import android.service.quicksettings.Tile import androidx.annotation.RequiresApi import androidx.core.content.getSystemService import io.nekohasekai.sagernet.R import io.nekohasekai.sagernet.SagerNet import io.nekohasekai.sagernet.aidl.ISagerNetService import io.nekohasekai.sagernet.database.DataStore import android.service.quicksettings.TileService as BaseTileService @RequiresApi(24) class TileService : BaseTileService(), SagerConnection.Callback { private val iconIdle by lazy { Icon.createWithResource(this, R.drawable.ic_service_active) } private val iconBusy by lazy { Icon.createWithResource(this, R.drawable.ic_service_active) } private val iconConnected by lazy { Icon.createWithResource(this, R.drawable.ic_service_active) } private val keyguard by lazy { getSystemService()!! } private var tapPending = false private val connection = SagerConnection() override fun stateChanged(state: BaseService.State, profileName: String?, msg: String?) = updateTile(state) { profileName } override fun onServiceConnected(service: ISagerNetService) { updateTile(BaseService.State.entries[service.state]) { service.profileName } if (tapPending) { tapPending = false onClick() } } override fun onStartListening() { super.onStartListening() connection.connect(this, this) } override fun onStopListening() { connection.disconnect(this) super.onStopListening() } override fun onClick() { if (isLocked) unlockAndRun(this::toggle) else toggle() } private fun updateTile(serviceState: BaseService.State, profileName: () -> String?) { qsTile?.apply { label = null when (serviceState) { BaseService.State.Idle -> error("serviceState") BaseService.State.Connecting -> { icon = iconBusy state = Tile.STATE_ACTIVE } BaseService.State.Connected -> { icon = iconConnected if (!keyguard.isDeviceLocked) label = profileName() state = Tile.STATE_ACTIVE } BaseService.State.Stopping -> { icon = iconBusy state = Tile.STATE_UNAVAILABLE } BaseService.State.Stopped -> { icon = iconIdle state = Tile.STATE_INACTIVE } } label = label ?: getString(R.string.app_name) updateTile() } } private fun toggle() { val service = connection.service if (service == null) tapPending = true else BaseService.State.entries[service.state].let { state -> when { state.canStop -> SagerNet.stopService() state == BaseService.State.Stopped -> SagerNet.startService() } } } }