diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncChannelJobService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncChannelJobService.java deleted file mode 100644 index 596f60cd8f..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncChannelJobService.java +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.services; - -import android.annotation.TargetApi; -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.content.ContentUris; -import android.content.Context; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.media.tv.TvContract; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.util.Log; - -import androidx.tvprovider.media.tv.Channel; -import androidx.tvprovider.media.tv.ChannelLogoUtils; -import androidx.tvprovider.media.tv.TvContractCompat; - -import org.dolphinemu.dolphinemu.R; -import org.dolphinemu.dolphinemu.model.HomeScreenChannel; -import org.dolphinemu.dolphinemu.utils.TvUtil; - -import java.util.ArrayList; -import java.util.List; - -public class SyncChannelJobService extends JobService -{ - private static final String TAG = "ChannelJobSvc"; - - private SyncChannelTask mSyncChannelTask; - - @Override - public boolean onStartJob(final JobParameters jobParameters) - { - Log.d(TAG, "Starting channel creation job"); - mSyncChannelTask = - new SyncChannelTask(getApplicationContext()) - { - @Override - protected void onPostExecute(Boolean success) - { - super.onPostExecute(success); - jobFinished(jobParameters, !success); - } - }; - mSyncChannelTask.execute(); - return true; - } - - @Override - public boolean onStopJob(JobParameters jobParameters) - { - if (mSyncChannelTask != null) - { - mSyncChannelTask.cancel(true); - } - return true; - } - - private static class SyncChannelTask extends AsyncTask - { - private Context context; - - SyncChannelTask(Context context) - { - this.context = context; - } - - /** - * Setup channels - */ - @TargetApi(Build.VERSION_CODES.O) - @Override - protected Boolean doInBackground(Void... voids) - { - List subscriptions; - List channels = TvUtil.getAllChannels(context); - List channelIds = new ArrayList<>(); - // Checks if the default channels are added. - // If not, create the channels - if (!channels.isEmpty()) - { - channels.forEach(channel -> channelIds.add(channel.getId())); - } - else - { - subscriptions = TvUtil.createUniversalSubscriptions(context); - for (HomeScreenChannel subscription : subscriptions) - { - long channelId = createChannel(subscription); - channelIds.add(channelId); - subscription.setChannelId(channelId); - // Only the first channel added can be browsable without user intervention. - TvContractCompat.requestChannelBrowsable(context, channelId); - } - } - // Schedule triggers to update programs - channelIds.forEach(channel -> TvUtil.scheduleSyncingProgramsForChannel(context, channel)); - // Update all channels - TvUtil.updateAllChannels(context); - return true; - } - - private long createChannel(HomeScreenChannel subscription) - { - long channelId = getChannelIdFromTvProvider(context, subscription); - if (channelId != -1L) - { - return channelId; - } - - // Create the channel since it has not been added to the TV Provider. - Uri appLinkIntentUri = subscription.getAppLinkIntentUri(); - - Channel.Builder builder = new Channel.Builder(); - builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) - .setDisplayName(subscription.getName()) - .setDescription(subscription.getDescription()) - .setAppLinkIntentUri(appLinkIntentUri); - - Log.d(TAG, "Creating channel: " + subscription.getName()); - Uri channelUrl = - context.getContentResolver() - .insert( - TvContractCompat.Channels.CONTENT_URI, - builder.build().toContentValues()); - - channelId = ContentUris.parseId(channelUrl); - Bitmap bitmap = TvUtil.convertToBitmap(context, R.drawable.ic_dolphin_launcher); - ChannelLogoUtils.storeChannelLogo(context, channelId, bitmap); - - return channelId; - } - - private long getChannelIdFromTvProvider(Context context, HomeScreenChannel subscription) - { - Cursor cursor = - context.getContentResolver().query( - TvContractCompat.Channels.CONTENT_URI, - new String[]{ - TvContractCompat.Channels._ID, - TvContract.Channels.COLUMN_DISPLAY_NAME - }, - null, - null, - null); - if (cursor != null && cursor.moveToFirst()) - { - do - { - Channel channel = Channel.fromCursor(cursor); - if (subscription.getName().equals(channel.getDisplayName())) - { - Log.d( - TAG, - "Channel already exists. Returning channel " - + channel.getId() - + " from TV Provider."); - return channel.getId(); - } - } - while (cursor.moveToNext()); - } - return -1L; - } - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncChannelJobService.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncChannelJobService.kt new file mode 100644 index 0000000000..e21b63bbfd --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/SyncChannelJobService.kt @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +@file:Suppress("DEPRECATION") + +package org.dolphinemu.dolphinemu.services + +import android.annotation.TargetApi +import android.app.job.JobParameters +import android.app.job.JobService +import android.content.ContentUris +import android.content.Context +import android.graphics.Bitmap +import android.media.tv.TvContract +import android.net.Uri +import android.os.AsyncTask +import android.os.Build +import android.util.Log +import androidx.tvprovider.media.tv.Channel +import androidx.tvprovider.media.tv.ChannelLogoUtils +import androidx.tvprovider.media.tv.TvContractCompat +import org.dolphinemu.dolphinemu.R +import org.dolphinemu.dolphinemu.model.HomeScreenChannel +import org.dolphinemu.dolphinemu.utils.TvUtil + +class SyncChannelJobService : JobService() { + private var syncChannelTask: SyncChannelTask? = null + + override fun onStartJob(jobParameters: JobParameters): Boolean { + Log.d(TAG, "Starting channel creation job") + syncChannelTask = object : SyncChannelTask(applicationContext) { + override fun onPostExecute(success: Boolean?) { + super.onPostExecute(success) + jobFinished(jobParameters, success != true) + } + } + syncChannelTask!!.execute() + return true + } + + override fun onStopJob(jobParameters: JobParameters): Boolean { + syncChannelTask?.cancel(true) + return true + } + + private open class SyncChannelTask(private val context: Context) : + AsyncTask() { + /** + * Setup channels + */ + @TargetApi(Build.VERSION_CODES.O) + override fun doInBackground(vararg voids: Void?): Boolean { + val channels: List = TvUtil.getAllChannels(context) + val channelIds = ArrayList() + + // Checks if the default channels are added. + // If not, create the channels + if (channels.isNotEmpty()) { + channels.forEach { channel -> channelIds.add(channel.id) } + } else { + for (subscription in TvUtil.createUniversalSubscriptions(context)) { + val channelId = createChannel(subscription) + channelIds.add(channelId) + subscription.channelId = channelId + // Only the first channel added can be browsable without user intervention. + TvContractCompat.requestChannelBrowsable(context, channelId) + } + } + + // Schedule triggers to update programs + channelIds.forEach { channel -> + TvUtil.scheduleSyncingProgramsForChannel( + context, channel + ) + } + // Update all channels + TvUtil.updateAllChannels(context) + return true + } + + private fun createChannel(subscription: HomeScreenChannel): Long { + var channelId = getChannelIdFromTvProvider(context, subscription) + if (channelId != -1L) { + return channelId + } + + // Create the channel since it has not been added to the TV Provider. + val appLinkIntentUri: Uri = subscription.appLinkIntentUri + + val builder = Channel.Builder() + builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) + .setDisplayName(subscription.name).setDescription(subscription.description) + .setAppLinkIntentUri(appLinkIntentUri) + + Log.d(TAG, "Creating channel: ${subscription.name}") + val channelUrl = context.contentResolver.insert( + TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues() + ) + + channelId = ContentUris.parseId(channelUrl!!) + val bitmap: Bitmap = TvUtil.convertToBitmap(context, R.drawable.ic_dolphin_launcher) + ChannelLogoUtils.storeChannelLogo(context, channelId, bitmap) + + return channelId + } + + private fun getChannelIdFromTvProvider( + context: Context, subscription: HomeScreenChannel + ): Long { + val cursor = context.contentResolver.query( + TvContractCompat.Channels.CONTENT_URI, arrayOf( + TvContractCompat.Channels._ID, TvContract.Channels.COLUMN_DISPLAY_NAME + ), null, null, null + ) + if (cursor != null && cursor.moveToFirst()) { + do { + val channel = Channel.fromCursor(cursor) + if (subscription.name == channel.displayName) { + Log.d( + TAG, + "Channel already exists. Returning channel " + channel.id + " from TV Provider." + ) + return channel.id + } + } while (cursor.moveToNext()) + } + return -1L + } + } + + companion object { + private const val TAG = "ChannelJobSvc" + } +}