• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.wallpaper.util
17 
18 import android.content.ContentResolver
19 import android.content.Context
20 import android.content.Intent
21 import android.content.pm.PackageManager
22 import android.content.pm.ProviderInfo
23 import android.net.Uri
24 import android.os.Bundle
25 import android.os.Handler
26 import android.os.Looper
27 import android.text.TextUtils
28 import java.util.concurrent.Executors
29 
30 /** Util class for wallpaper preview. */
31 class PreviewUtils(
32     private val context: Context,
33     authorityMetadataKey: String? = null,
34     authority: String? = null,
35 ) {
36     /** Callback for a call to the provider to render preview */
37     interface WorkspacePreviewCallback {
38         /** Called with the result from the provider. */
onPreviewRenderednull39         fun onPreviewRendered(resultBundle: Bundle?)
40     }
41 
42     private var providerInfo: ProviderInfo?
43 
44     constructor(
45         context: Context,
46         authorityMetadataKey: String,
47     ) : this(
48         context = context,
49         authorityMetadataKey = authorityMetadataKey,
50         authority = null,
51     )
52 
53     init {
54         val providerAuthority =
55             authority ?: homeAuthority(context, checkNotNull(authorityMetadataKey))
56 
57         providerInfo =
58             if (!TextUtils.isEmpty(providerAuthority)) {
59                 context.packageManager.resolveContentProvider(
60                     providerAuthority,
61                     0,
62                 )
63             } else {
64                 null
65             }
66 
67         providerInfo?.let {
68             if (!TextUtils.isEmpty(it.readPermission)) {
69                 if (
70                     context.checkSelfPermission(it.readPermission) !=
71                         PackageManager.PERMISSION_GRANTED
72                 ) {
73                     providerInfo = null
74                 }
75             }
76         }
77     }
78 
79     /**
80      * Render preview under the current grid option.
81      *
82      * @param bundle request options to pass on the call.
83      * @param callback to receive the results, it will be called on the main thread.
84      */
renderPreviewnull85     fun renderPreview(bundle: Bundle?, callback: WorkspacePreviewCallback) {
86         EXECUTOR_SERVICE.submit {
87             val result =
88                 context.contentResolver.call(
89                     getUri(PREVIEW),
90                     METHOD_GET_PREVIEW,
91                     null,
92                     bundle,
93                 )
94             Handler(Looper.getMainLooper()).post { callback.onPreviewRendered(result) }
95         }
96     }
97 
98     /** Easy way to generate a Uri with the provider info from this class. */
getUrinull99     fun getUri(path: String?): Uri {
100         return Uri.Builder()
101             .scheme(ContentResolver.SCHEME_CONTENT)
102             .authority(checkNotNull(providerInfo).authority)
103             .appendPath(path)
104             .build()
105     }
106 
107     /** Return whether preview is supported. */
supportsPreviewnull108     fun supportsPreview(): Boolean {
109         return providerInfo != null
110     }
111 
112     companion object {
113         private const val PREVIEW = "preview"
114         private const val METHOD_GET_PREVIEW = "get_preview"
115         private val EXECUTOR_SERVICE = Executors.newSingleThreadExecutor()
116 
homeAuthoritynull117         private fun homeAuthority(context: Context, authorityMetadataKey: String): String? {
118             val homeIntent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
119             val info =
120                 context.packageManager.resolveActivity(
121                     homeIntent,
122                     PackageManager.MATCH_DEFAULT_ONLY or PackageManager.GET_META_DATA,
123                 )
124 
125             return info?.activityInfo?.metaData?.getString(authorityMetadataKey)
126         }
127     }
128 }
129