1 /*
2  * Copyright (C) 2022 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.intentresolver.shortcuts
17 
18 import android.app.prediction.AppPredictionContext
19 import android.app.prediction.AppPredictionManager
20 import android.app.prediction.AppPredictor
21 import android.content.Context
22 import android.content.IntentFilter
23 import android.os.Bundle
24 import android.os.UserHandle
25 
26 // TODO(b/123088566) Share these in a better way.
27 private const val APP_PREDICTION_SHARE_UI_SURFACE = "share"
28 private const val APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20
29 private const val APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter"
30 private const val SHARED_TEXT_KEY = "shared_text"
31 
32 /**
33  * A factory to create an AppPredictor instance for a profile, if available.
34  *
35  * @param context, application context
36  * @param sharedText, a shared text associated with the Chooser's target intent (see
37  *   [android.content.Intent.EXTRA_TEXT]). Will be mapped to app predictor's "shared_text"
38  *   parameter.
39  * @param targetIntentFilter, an IntentFilter to match direct share targets against. Will be mapped
40  *   app predictor's "intent_filter" parameter.
41  */
42 class AppPredictorFactory(
43     private val context: Context,
44     private val sharedText: String?,
45     private val targetIntentFilter: IntentFilter?,
46     private val appPredictionAvailable: Boolean,
47 ) {
48     /**
49      * Creates an AppPredictor instance for a profile or `null` if app predictor is not available.
50      */
createnull51     fun create(userHandle: UserHandle): AppPredictor? {
52         if (!appPredictionAvailable) return null
53         val contextAsUser = context.createContextAsUser(userHandle, 0 /* flags */)
54         val extras =
55             Bundle().apply {
56                 putParcelable(APP_PREDICTION_INTENT_FILTER_KEY, targetIntentFilter)
57                 putString(SHARED_TEXT_KEY, sharedText)
58             }
59         val appPredictionContext =
60             AppPredictionContext.Builder(contextAsUser)
61                 .setUiSurface(APP_PREDICTION_SHARE_UI_SURFACE)
62                 .setPredictedTargetCount(APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT)
63                 .setExtras(extras)
64                 .build()
65         return contextAsUser
66             .getSystemService(AppPredictionManager::class.java)
67             ?.createAppPredictionSession(appPredictionContext)
68     }
69 }
70