<commit_before>package de.christinecoenen.code.zapp.app.player

import android.app.*
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Bitmap
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.ui.PlayerNotificationManager.BitmapCallback
import com.google.android.exoplayer2.ui.PlayerNotificationManager.MediaDescriptionAdapter
import de.christinecoenen.code.zapp.R
import de.christinecoenen.code.zapp.app.ZappApplication
import de.christinecoenen.code.zapp.utils.system.NotificationHelper
import io.reactivex.disposables.Disposable
import timber.log.Timber

class BackgroundPlayerService : IntentService("BackgroundPlayerService"),
	MediaDescriptionAdapter,
	PlayerNotificationManager.NotificationListener {


	companion object {

		private const val ACTION_START_IN_BACKGROUND =
			"de.christinecoenen.code.zapp.app.mediathek.controller.action.START_IN_BACKGROUND"

		/**
		 * Binds this service to the given context.
		 *
		 * @param context
		 * @param serviceConnection will be used to pass a [Binder] instance
		 * for further communication with this service
		 */
		@JvmStatic
		fun bind(context: Context, serviceConnection: ServiceConnection?) {
			val intent = Intent(context, BackgroundPlayerService::class.java)
			context.bindService(intent, serviceConnection!!, Context.BIND_AUTO_CREATE)
		}

		private fun startInBackground(context: Context) {
			val intent = Intent(context, BackgroundPlayerService::class.java)
			intent.action = ACTION_START_IN_BACKGROUND
			context.startService(intent)
		}
	}


	private val binder = Binder()

	private lateinit var player: Player
	private lateinit var errorMessageDisposable: Disposable

	private var playerNotificationManager: PlayerNotificationManager? = null
	private var foregroundActivityIntent: Intent? = null
	private var isPlaybackInBackground = false

	/**
	 * This service is only running when
	 * 1. an UI element is currently bound and not in paused state OR
	 * 2. the playback is running in background
	 *
	 * So is is save to aquire locks and release them in [.onDestroy]
	 */
	override fun onCreate() {
		super.onCreate()

		val application = applicationContext as ZappApplication

		player = Player(this, application.playbackPositionRepository)
		errorMessageDisposable = player.errorResourceId.subscribe(this::onPlayerError)
	}

	override fun onBind(intent: Intent): IBinder? = binder

	override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
		handleIntent(intent)
		return Service.START_STICKY
	}

	override fun onHandleIntent(intent: Intent?) {}

	override fun onTaskRemoved(rootIntent: Intent) {
		super.onTaskRemoved(rootIntent)
		onDestroy()
	}

	override fun onDestroy() {
		movePlaybackToForeground()

		player.destroy()
		errorMessageDisposable.dispose()

		super.onDestroy()
	}<commit_msg>Fix lint warning regarding nullability<commit_after>package de.christinecoenen.code.zapp.app.player

import android.app.*
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Bitmap
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.ui.PlayerNotificationManager.BitmapCallback
import com.google.android.exoplayer2.ui.PlayerNotificationManager.MediaDescriptionAdapter
import de.christinecoenen.code.zapp.R
import de.christinecoenen.code.zapp.app.ZappApplication
import de.christinecoenen.code.zapp.utils.system.NotificationHelper
import io.reactivex.disposables.Disposable
import timber.log.Timber

class BackgroundPlayerService : IntentService("BackgroundPlayerService"),
	MediaDescriptionAdapter,
	PlayerNotificationManager.NotificationListener {


	companion object {

		private const val ACTION_START_IN_BACKGROUND =
			"de.christinecoenen.code.zapp.app.mediathek.controller.action.START_IN_BACKGROUND"

		/**
		 * Binds this service to the given context.
		 *
		 * @param context
		 * @param serviceConnection will be used to pass a [Binder] instance
		 * for further communication with this service
		 */
		@JvmStatic
		fun bind(context: Context, serviceConnection: ServiceConnection?) {
			val intent = Intent(context, BackgroundPlayerService::class.java)
			context.bindService(intent, serviceConnection!!, Context.BIND_AUTO_CREATE)
		}

		private fun startInBackground(context: Context) {
			val intent = Intent(context, BackgroundPlayerService::class.java)
			intent.action = ACTION_START_IN_BACKGROUND
			context.startService(intent)
		}
	}


	private val binder = Binder()

	private lateinit var player: Player
	private lateinit var errorMessageDisposable: Disposable

	private var playerNotificationManager: PlayerNotificationManager? = null
	private var foregroundActivityIntent: Intent? = null
	private var isPlaybackInBackground = false

	/**
	 * This service is only running when
	 * 1. an UI element is currently bound and not in paused state OR
	 * 2. the playback is running in background
	 *
	 * So is is save to aquire locks and release them in [.onDestroy]
	 */
	override fun onCreate() {
		super.onCreate()

		val application = applicationContext as ZappApplication

		player = Player(this, application.playbackPositionRepository)
		errorMessageDisposable = player.errorResourceId.subscribe(this::onPlayerError)
	}

	override fun onBind(intent: Intent): IBinder = binder

	override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
		handleIntent(intent)
		return Service.START_STICKY
	}

	override fun onHandleIntent(intent: Intent?) {}

	override fun onTaskRemoved(rootIntent: Intent) {
		super.onTaskRemoved(rootIntent)
		onDestroy()
	}

	override fun onDestroy() {
		movePlaybackToForeground()

		player.destroy()
		errorMessageDisposable.dispose()

		super.onDestroy()
	}
{'fraction_non_alphanumeric': 0.07867936925098555, 'fraction_numerical': 0.0016425755584756898, 'mean_word_length': 5.4162276080084295, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2501372', 'n_tokens_mistral': 1834, 'n_tokens_neox': 1648, 'n_words': 424}