1 /* 2 * Copyright (C) 2021 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.shell; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.net.Uri; 26 import android.util.Log; 27 28 import androidx.core.content.FileProvider; 29 30 import com.android.internal.R; 31 32 import java.io.File; 33 import java.util.List; 34 35 /** 36 * A proxy service that relays report upload requests to the uploader app, while translating 37 * the path to the report to a content URI owned by this service. 38 */ 39 public final class ProfcollectUploadReceiver extends BroadcastReceiver { 40 private static final String AUTHORITY = "com.android.shell"; 41 private static final String PROFCOLLECT_DATA_ROOT = "/data/misc/profcollectd/report/"; 42 43 private static final String LOG_TAG = "ProfcollectUploadReceiver"; 44 45 @Override onReceive(Context context, Intent intent)46 public void onReceive(Context context, Intent intent) { 47 Log.i(LOG_TAG, "Received upload intent"); 48 49 String uploaderPkg = getUploaderPackageName(context); 50 String uploaderAction = getUploaderActionName(context); 51 52 try { 53 ApplicationInfo info = context.getPackageManager().getApplicationInfo(uploaderPkg, 54 0); 55 if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 56 Log.e(LOG_TAG, "The profcollect uploader app " + uploaderPkg 57 + " must be a system application"); 58 return; 59 } 60 } catch (PackageManager.NameNotFoundException e) { 61 Log.e(LOG_TAG, "Cannot find profcollect uploader app " + uploaderPkg); 62 return; 63 } 64 65 String filename = intent.getStringExtra("filename"); 66 File reportFile = new File(PROFCOLLECT_DATA_ROOT + filename); 67 Uri reportUri = FileProvider.getUriForFile(context, AUTHORITY, reportFile); 68 Intent uploadIntent = 69 new Intent(uploaderAction) 70 .setPackage(uploaderPkg) 71 .putExtra("EXTRA_DESTINATION", "PROFCOLLECT") 72 .putExtra("EXTRA_PACKAGE_NAME", context.getPackageName()) 73 .setData(reportUri) 74 .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 75 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 76 77 List<ResolveInfo> receivers = 78 context.getPackageManager().queryBroadcastReceivers(uploadIntent, 0); 79 if (receivers == null || receivers.isEmpty()) { 80 Log.e(LOG_TAG, "No one to receive upload intent, abort upload."); 81 return; 82 } 83 84 context.grantUriPermission(uploaderPkg, reportUri, 85 Intent.FLAG_GRANT_READ_URI_PERMISSION); 86 context.sendBroadcast(uploadIntent); 87 } 88 getUploaderPackageName(Context context)89 private String getUploaderPackageName(Context context) { 90 return context.getResources().getString( 91 R.string.config_defaultProfcollectReportUploaderApp); 92 } 93 getUploaderActionName(Context context)94 private String getUploaderActionName(Context context) { 95 return context.getResources().getString( 96 R.string.config_defaultProfcollectReportUploaderAction); 97 } 98 } 99