Warning, /network/kdeconnect-android/src/org/kde/kdeconnect/UserInterface/About/EasterEggActivity.kt is written in an unsupported language. File is not indexed.

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Maxim Leshchenko <cnmaks90@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 package org.kde.kdeconnect.UserInterface.About
0008 
0009 import android.animation.ValueAnimator
0010 import android.content.pm.ActivityInfo
0011 import android.graphics.Color
0012 import android.hardware.Sensor
0013 import android.hardware.SensorEvent
0014 import android.hardware.SensorEventListener
0015 import android.hardware.SensorManager
0016 import android.os.Bundle
0017 import android.view.View
0018 import androidx.appcompat.app.AppCompatActivity
0019 import androidx.core.content.ContextCompat
0020 import org.kde.kdeconnect_tp.R
0021 import org.kde.kdeconnect_tp.databinding.ActivityEasterEggBinding
0022 import kotlin.math.PI
0023 import kotlin.math.atan2
0024 
0025 private val KDE_ICON_BACKGROUND_COLOR = Color.rgb(29, 153, 243)
0026 private val KONQI_BACKGROUND_COLOR = Color.rgb(191, 255, 0)
0027 
0028 class EasterEggActivity : AppCompatActivity(), SensorEventListener {
0029     private var binding: ActivityEasterEggBinding? = null
0030     private lateinit var sensorManager: SensorManager
0031     private val animator = ValueAnimator()
0032     private var isAlreadyLongClicked = false
0033 
0034     override fun onCreate(savedInstanceState: Bundle?) {
0035         super.onCreate(savedInstanceState)
0036 
0037         binding = ActivityEasterEggBinding.inflate(layoutInflater)
0038         setContentView(binding!!.root)
0039 
0040         requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
0041 
0042         // Make the status bar blue to make the Easter Egg beautiful
0043         window.statusBarColor = KDE_ICON_BACKGROUND_COLOR
0044         window.navigationBarColor = KDE_ICON_BACKGROUND_COLOR
0045         setLightSystemWindowsEnabled(false)
0046 
0047         sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
0048         if (hasAccelerometer()) {
0049             animator.addUpdateListener {
0050                 binding!!.logo.rotation = animator.animatedValue as Float
0051             }
0052             animator.duration = 300
0053         } else {
0054             binding!!.angle.visibility = View.GONE
0055         }
0056 
0057         // Make Easter Egg more fun
0058         binding!!.easterEggLayout.setOnLongClickListener {
0059             if (!isAlreadyLongClicked) {
0060                 isAlreadyLongClicked = true
0061 
0062                 binding!!.easterEggLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.activity_background))
0063                 binding!!.logo.setColorFilter(ContextCompat.getColor(this, R.color.text_color))
0064                 binding!!.angle.setTextColor(ContextCompat.getColor(this, R.color.text_color))
0065 
0066                 var typedArray = this.theme.obtainStyledAttributes(intArrayOf(android.R.attr.statusBarColor))
0067                 window.statusBarColor = typedArray.getColor(0, Color.WHITE)
0068                 window.navigationBarColor = typedArray.getColor(0, Color.WHITE)
0069 
0070                 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
0071                     typedArray = this.theme.obtainStyledAttributes(intArrayOf(android.R.attr.windowLightStatusBar))
0072                     setLightSystemWindowsEnabled(typedArray.getBoolean(0, true))
0073                 }
0074 
0075                 typedArray.recycle()
0076             }
0077 
0078             val icon = intArrayOf(
0079                     R.drawable.ic_action_keyboard_24dp, R.drawable.ic_action_refresh_24dp,
0080                     R.drawable.ic_action_image_edit_24dp, R.drawable.ic_arrow_upward_black_24dp,
0081                     R.drawable.ic_baseline_attach_money_24, R.drawable.ic_baseline_bug_report_24,
0082                     R.drawable.ic_baseline_code_24, R.drawable.ic_baseline_gavel_24,
0083                     R.drawable.ic_baseline_info_24, R.drawable.ic_baseline_web_24,
0084                     R.drawable.ic_baseline_send_24, R.drawable.ic_baseline_sms_24,
0085                     R.drawable.ic_accept_pairing_24dp, R.drawable.ic_share_white,
0086                     R.drawable.ic_delete,
0087                     R.drawable.ic_device_laptop_32dp, R.drawable.ic_device_phone_32dp,
0088                     R.drawable.ic_device_tablet_32dp, R.drawable.ic_device_tv_32dp,
0089                     R.drawable.ic_delete, R.drawable.ic_warning,
0090                     R.drawable.ic_volume_black, R.drawable.ic_wifi,
0091                     R.drawable.ic_add, R.drawable.touchpad_plugin_action_24dp,
0092                     R.drawable.konqi, R.drawable.run_command_plugin_icon_24dp,
0093                     R.drawable.ic_phonelink_36dp, R.drawable.ic_phonelink_off_36dp,
0094                     R.drawable.ic_error_outline_48dp, R.drawable.ic_home_black_24dp,
0095                     R.drawable.ic_settings_white_32dp, R.drawable.ic_stop,
0096                     R.drawable.ic_rewind_black, R.drawable.ic_play_black,
0097                     R.drawable.ic_mic_black, R.drawable.ic_pause_black,
0098                     R.drawable.ic_volume_mute_black, R.drawable.ic_arrow_upward_black_24dp,
0099                     R.drawable.ic_next_black, R.drawable.ic_previous_black,
0100                     R.drawable.ic_presenter_24dp, R.drawable.ic_key,
0101                     R.drawable.ic_keyboard_return_black_24dp, R.drawable.ic_keyboard_hide_36dp,
0102                     R.drawable.ic_kde_24dp, R.drawable.ic_album_art_placeholder,
0103                     R.drawable.ic_arrow_back_black_24dp, R.drawable.share_plugin_action_24dp
0104             ).random()
0105 
0106             if (icon == R.drawable.konqi) {
0107                 binding!!.logo.clearColorFilter()
0108                 binding!!.easterEggLayout.setBackgroundColor(KONQI_BACKGROUND_COLOR)
0109                 window.statusBarColor = KONQI_BACKGROUND_COLOR
0110                 window.navigationBarColor = KONQI_BACKGROUND_COLOR
0111                 isAlreadyLongClicked = false
0112             }
0113 
0114             binding!!.logo.setImageResource(icon)
0115 
0116             true
0117         }
0118     }
0119 
0120     private fun hasAccelerometer(): Boolean = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null
0121 
0122     private fun setLightSystemWindowsEnabled(enabled: Boolean) {
0123         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
0124             if (enabled) {
0125                 window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
0126             } else {
0127                 window.decorView.systemUiVisibility = window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
0128             }
0129         }
0130 
0131         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
0132             if (enabled) {
0133                 window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
0134             } else {
0135                 window.decorView.systemUiVisibility = window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
0136             }
0137         }
0138     }
0139 
0140     override fun onResume() {
0141         super.onResume()
0142         if (hasAccelerometer()) {
0143             sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI)
0144         }
0145     }
0146 
0147     override fun onPause() {
0148         if (hasAccelerometer()) {
0149             sensorManager.unregisterListener(this)
0150         }
0151         super.onPause()
0152     }
0153 
0154     override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { }
0155     override fun onSensorChanged(event: SensorEvent) {
0156         if (binding != null) {
0157             val axisX = event.values[0]
0158             val axisY = event.values[1]
0159 
0160             val angle = (atan2(axisX, axisY) / (PI / 180)).toInt()
0161             binding!!.angle.text = angle.toString() + "°"
0162 
0163             animator.setFloatValues(binding!!.logo.rotation, angle.toFloat())
0164             animator.start()
0165         }
0166     }
0167 }