1 /*
2  * Copyright (C) 2023 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 
17 package com.android.intentresolver.icons;
18 
19 import android.content.Context;
20 import android.content.PermissionChecker;
21 import android.content.pm.ActivityInfo;
22 import android.os.AsyncTask;
23 import android.os.Trace;
24 
25 import com.android.intentresolver.R;
26 import com.android.intentresolver.TargetPresentationGetter;
27 import com.android.intentresolver.chooser.DisplayResolveInfo;
28 
29 import java.util.function.Consumer;
30 
31 class LoadLabelTask extends AsyncTask<Void, Void, LabelInfo> {
32     private final Context mContext;
33     private final DisplayResolveInfo mDisplayResolveInfo;
34     private final boolean mIsAudioCaptureDevice;
35     protected final TargetPresentationGetter.Factory mPresentationFactory;
36     private final Consumer<LabelInfo> mCallback;
37 
LoadLabelTask(Context context, DisplayResolveInfo dri, boolean isAudioCaptureDevice, TargetPresentationGetter.Factory presentationFactory, Consumer<LabelInfo> callback)38     LoadLabelTask(Context context, DisplayResolveInfo dri,
39             boolean isAudioCaptureDevice, TargetPresentationGetter.Factory presentationFactory,
40             Consumer<LabelInfo> callback) {
41         mContext = context;
42         mDisplayResolveInfo = dri;
43         mIsAudioCaptureDevice = isAudioCaptureDevice;
44         mPresentationFactory = presentationFactory;
45         mCallback = callback;
46     }
47 
48     @Override
doInBackground(Void... voids)49     protected LabelInfo doInBackground(Void... voids) {
50         try {
51             Trace.beginSection("app-label");
52             return loadLabel(
53                     mContext, mDisplayResolveInfo, mIsAudioCaptureDevice, mPresentationFactory);
54         } finally {
55             Trace.endSection();
56         }
57     }
58 
loadLabel( Context context, DisplayResolveInfo displayResolveInfo, boolean isAudioCaptureDevice, TargetPresentationGetter.Factory presentationFactory)59     static LabelInfo loadLabel(
60             Context context,
61             DisplayResolveInfo displayResolveInfo,
62             boolean isAudioCaptureDevice,
63             TargetPresentationGetter.Factory presentationFactory) {
64         TargetPresentationGetter pg = presentationFactory.makePresentationGetter(
65                 displayResolveInfo.getResolveInfo());
66 
67         if (isAudioCaptureDevice) {
68             // This is an audio capture device, so check record permissions
69             ActivityInfo activityInfo = displayResolveInfo.getResolveInfo().activityInfo;
70             String packageName = activityInfo.packageName;
71 
72             int uid = activityInfo.applicationInfo.uid;
73             boolean hasRecordPermission =
74                     PermissionChecker.checkPermissionForPreflight(
75                             context,
76                             android.Manifest.permission.RECORD_AUDIO, -1, uid,
77                             packageName)
78                             == android.content.pm.PackageManager.PERMISSION_GRANTED;
79 
80             if (!hasRecordPermission) {
81                 // Doesn't have record permission, so warn the user
82                 return new LabelInfo(
83                         pg.getLabel(),
84                         context.getString(R.string.usb_device_resolve_prompt_warn));
85             }
86         }
87 
88         return new LabelInfo(
89                 pg.getLabel(),
90                 pg.getSubLabel());
91     }
92 
93     @Override
onPostExecute(LabelInfo result)94     protected void onPostExecute(LabelInfo result) {
95         mCallback.accept(result);
96     }
97 }
98