1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 package com.android.tv.settings.util 17 18 import com.android.tv.twopanelsettings.slices.base.SliceManager 19 import android.content.Context 20 import android.net.Uri 21 import android.util.Log 22 import kotlinx.coroutines.Dispatchers 23 import kotlinx.coroutines.withContext 24 25 @Suppress("DEPRECATION") // Slices are still supported for TV Settings. 26 object SliceUtilsKt { 27 private const val TAG = "SliceUtilsKt" 28 29 /** 30 * Checks if the slice is available in the background if needed 31 * 32 * @param context Current context of the app 33 * @param uri Settings slice uri 34 * @param topLevelSettingsSliceUri Top level settings slice uri, if null, use provided uri to 35 * deduce top level settings slice uri. 36 * @return returns true if slice is enabled, false otherwise 37 */ 38 @JvmStatic isSettingsSliceEnablednull39 suspend fun isSettingsSliceEnabled(context: Context, uri: String?, 40 topLevelSettingsSliceUri: String?): Boolean { 41 if (uri == null) { 42 return false 43 } 44 val sliceManager = SliceManager.from(context) 45 return withContext(Dispatchers.IO) { 46 return@withContext isSettingsSliceEnabledInternal( 47 context, sliceManager, 48 uri, topLevelSettingsSliceUri 49 ) 50 } 51 } 52 53 /** 54 * Checks if the slice is available in the background if needed 55 * 56 * @param context Current context of the app 57 * @param uri Settings slice uri 58 * @param topLevelSettingsSliceUri Top level settings slice uri, if null, use provided uri to 59 * deduce top level settings slice uri. 60 * @return returns true if slice is enabled, false otherwise 61 */ 62 @JvmStatic isSettingsSliceEnabledSyncnull63 fun isSettingsSliceEnabledSync( 64 context: Context, uri: String?, 65 topLevelSettingsSliceUri: String? 66 ): Boolean { 67 if (uri == null) { 68 return false 69 } 70 val sliceManager = SliceManager.from(context) 71 return isSettingsSliceEnabledInternal(context, sliceManager, uri, topLevelSettingsSliceUri) 72 } 73 isSettingsSliceEnabledInternalnull74 private fun isSettingsSliceEnabledInternal( 75 context: Context, sliceManager: SliceManager, 76 uri: String, topLevelSettingsSliceUri: String? 77 ): Boolean { 78 val topLevelSettingsSlice = if (topLevelSettingsSliceUri == null) { 79 Uri.parse(uri).buildUpon().path("/").build() 80 } else { 81 Uri.parse(ResourcesUtil.getString(context, topLevelSettingsSliceUri)) 82 } 83 val enabledSlicesUri = sliceManager.getSliceDescendants(topLevelSettingsSlice) 84 if (enabledSlicesUri.isEmpty()) { 85 // SliceProvider likely does not support listing descendants. 86 return sliceManager.bindSlice(Uri.parse(uri), setOf()) != null 87 } 88 for (sliceUri in enabledSlicesUri) { 89 Log.i(TAG, "Enabled slice: $sliceUri") 90 if (sliceUri.toString() == uri) { 91 return true 92 } 93 } 94 return false 95 } 96 }