• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.uwb;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.os.BugreportManager;
22 import android.os.BugreportParams;
23 import android.util.Log;
24 
25 /**
26  * A class to trigger bugreport and other logs for UWB related failures
27  */
28 public class UwbDiagnostics {
29     private static final  String TAG = "UwbDiagnostics";
30     private final Context mContext;
31     private final SystemBuildProperties mSystemBuildProperties;
32     private final UwbInjector mUwbInjector;
33     private long mLastBugReportTimeMs;
UwbDiagnostics( Context context, UwbInjector uwbInjector, SystemBuildProperties systemBuildProperties)34     public UwbDiagnostics(
35             Context context, UwbInjector uwbInjector, SystemBuildProperties systemBuildProperties) {
36         mContext = context;
37         mSystemBuildProperties = systemBuildProperties;
38         mUwbInjector = uwbInjector;
39     }
40 
41     /**
42      * Take a bug report if it is in user debug build and there is no recent bug report
43      */
takeBugReport(String bugTitle)44     public void takeBugReport(String bugTitle) {
45         if (!mSystemBuildProperties.isUserdebugBuild()) {
46             Log.d(TAG, "Skip bugreport because it can be triggered only in userDebug build");
47             return;
48         }
49         long currentTimeMs = mUwbInjector.getElapsedSinceBootMillis();
50         long timeSinceLastUploadMs = currentTimeMs - mLastBugReportTimeMs;
51         if (timeSinceLastUploadMs
52                 < mUwbInjector.getDeviceConfigFacade().getBugReportMinIntervalMs()
53                 && mLastBugReportTimeMs > 0) {
54             Log.d(TAG, "Bugreport was filed recently, Skip " + bugTitle);
55             return;
56         }
57 
58         if (!takeBugreportThroughBetterBug(bugTitle)) {
59             takeBugreportThroughBugreportManager(bugTitle);
60         }
61     }
62 
takeBugreportThroughBetterBug(String bugTitle)63     private boolean takeBugreportThroughBetterBug(String bugTitle) {
64         Intent launchBetterBugIntent =
65                 new BetterBugIntentBuilder()
66                         .setIssueTitle(bugTitle)
67                         .setHappenedTimestamp(System.currentTimeMillis())
68                         .build();
69         boolean isIntentUnSafe = mContext
70                 .getPackageManager().queryIntentActivities(launchBetterBugIntent, 0)
71                 .isEmpty();
72         if (isIntentUnSafe) {
73             Log.d(TAG, "intent is unsafe and skip bugreport from betterBug: " + bugTitle);
74             return false;
75         }
76 
77         try {
78             launchBetterBugIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
79             mContext.startActivity(launchBetterBugIntent);
80             Log.d(TAG, "Taking the bugreport through betterBug: " + bugTitle);
81             mLastBugReportTimeMs = mUwbInjector.getElapsedSinceBootMillis();
82             return true;
83         } catch (RuntimeException e) {
84             Log.e(TAG, "Error taking bugreport: " + e);
85             return false;
86         }
87     }
88 
takeBugreportThroughBugreportManager(String bugTitle)89     private boolean takeBugreportThroughBugreportManager(String bugTitle) {
90         BugreportManager bugreportManager = mContext.getSystemService(BugreportManager.class);
91         BugreportParams params = new BugreportParams(BugreportParams.BUGREPORT_MODE_FULL);
92         try {
93             bugreportManager.requestBugreport(params, bugTitle, bugTitle);
94             Log.d(TAG, "Taking the bugreport through bugreportManager: " + bugTitle);
95             mLastBugReportTimeMs = mUwbInjector.getElapsedSinceBootMillis();
96             return true;
97         } catch (RuntimeException e) {
98             Log.e(TAG, "Error taking bugreport: " + e);
99             return false;
100         }
101     }
102 
103     /**
104      * @return the last time when the bug report is taken
105      */
getLastBugReportTimeMs()106     long getLastBugReportTimeMs() {
107         return mLastBugReportTimeMs;
108     }
109 
110     /**
111      * Builder for communicating with the betterbug.
112      */
113     private class BetterBugIntentBuilder {
114 
115         private static final String ACTION_FILE_BUG_DEEPLINK =
116                 "com.google.android.apps.betterbug.intent.FILE_BUG_DEEPLINK";
117         private static final boolean DEFAULT_AUTO_UPLOAD_ENABLED = false;
118         private static final boolean DEFAULT_BUGREPORT_REQUIRED = true;
119         private static final String DEFAULT_BUG_ASSIGNEE = "android-uwb-team@google.com";
120         private static final long DEFAULT_COMPONENT_ID = 1042770L;
121 
122         private static final String EXTRA_DEEPLINK = "EXTRA_DEEPLINK";
123         private static final String EXTRA_ISSUE_TITLE = "EXTRA_ISSUE_TITLE";
124         private static final String EXTRA_DEEPLINK_SILENT = "EXTRA_DEEPLINK_SILENT";
125         private static final String EXTRA_ADDITIONAL_COMMENT = "EXTRA_ADDITIONAL_COMMENT";
126         private static final String EXTRA_TARGET_PACKAGE = "EXTRA_TARGET_PACKAGE";
127         private static final String EXTRA_REQUIRE_BUGREPORT = "EXTRA_REQUIRE_BUGREPORT";
128         private static final String EXTRA_HAPPENED_TIME = "EXTRA_HAPPENED_TIME";
129         private static final String EXTRA_BUG_ASSIGNEE = "EXTRA_BUG_ASSIGNEE";
130         private static final String EXTRA_COMPONENT_ID = "EXTRA_COMPONENT_ID";
131 
132         private final Intent mBetterBugIntent;
133 
BetterBugIntentBuilder()134         BetterBugIntentBuilder() {
135             mBetterBugIntent = new Intent().setAction(ACTION_FILE_BUG_DEEPLINK)
136                     .putExtra(EXTRA_DEEPLINK, true);
137             setAutoUpload(DEFAULT_AUTO_UPLOAD_ENABLED);
138             setBugreportRequired(DEFAULT_BUGREPORT_REQUIRED);
139             setBugAssignee(DEFAULT_BUG_ASSIGNEE);
140             setComponentId(DEFAULT_COMPONENT_ID);
141         }
142 
setIssueTitle(String title)143         public BetterBugIntentBuilder setIssueTitle(String title) {
144             mBetterBugIntent.putExtra(EXTRA_ISSUE_TITLE, title);
145             return this;
146         }
147 
setAutoUpload(boolean autoUploadEnabled)148         public BetterBugIntentBuilder setAutoUpload(boolean autoUploadEnabled) {
149             mBetterBugIntent.putExtra(EXTRA_DEEPLINK_SILENT, autoUploadEnabled);
150             return this;
151         }
152 
setTargetPackage(String targetPackage)153         public BetterBugIntentBuilder setTargetPackage(String targetPackage) {
154             mBetterBugIntent.putExtra(EXTRA_TARGET_PACKAGE, targetPackage);
155             return this;
156         }
157 
setComponentId(long componentId)158         public BetterBugIntentBuilder setComponentId(long componentId) {
159             mBetterBugIntent.putExtra(EXTRA_COMPONENT_ID, componentId);
160             return this;
161         }
162 
setBugreportRequired(boolean isBugreportRequired)163         public BetterBugIntentBuilder setBugreportRequired(boolean isBugreportRequired) {
164             mBetterBugIntent.putExtra(EXTRA_REQUIRE_BUGREPORT, isBugreportRequired);
165             return this;
166         }
167 
setHappenedTimestamp(long happenedTimeSinceEpochMs)168         public BetterBugIntentBuilder setHappenedTimestamp(long happenedTimeSinceEpochMs) {
169             mBetterBugIntent.putExtra(EXTRA_HAPPENED_TIME, happenedTimeSinceEpochMs);
170             return this;
171         }
172 
setAdditionalComment(String additionalComment)173         public BetterBugIntentBuilder setAdditionalComment(String additionalComment) {
174             mBetterBugIntent.putExtra(EXTRA_ADDITIONAL_COMMENT, additionalComment);
175             return this;
176         }
177 
setBugAssignee(String assignee)178         public BetterBugIntentBuilder setBugAssignee(String assignee) {
179             mBetterBugIntent.putExtra(EXTRA_BUG_ASSIGNEE, assignee);
180             return this;
181         }
182 
build()183         public Intent build() {
184             return mBetterBugIntent;
185         }
186     }
187 }
188