1 /*
2  * Copyright (C) 2016 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 android.os;
18 
19 import android.annotation.RequiresPermission;
20 import android.annotation.SystemApi;
21 import android.annotation.SystemService;
22 import android.annotation.TestApi;
23 import android.content.Context;
24 import android.os.IIncidentManager;
25 import android.os.ServiceManager;
26 import android.provider.Settings;
27 import android.util.Slog;
28 
29 /**
30  * Class to take an incident report.
31  *
32  * @hide
33  */
34 @SystemApi
35 @TestApi
36 @SystemService(Context.INCIDENT_SERVICE)
37 public class IncidentManager {
38     private static final String TAG = "incident";
39 
40     private Context mContext;
41 
42     /**
43      * @hide
44      */
IncidentManager(Context context)45     public IncidentManager(Context context) {
46         mContext = context;
47     }
48 
49     /**
50      * Take an incident report and put it in dropbox.
51      */
52     @RequiresPermission(allOf = {
53             android.Manifest.permission.DUMP,
54             android.Manifest.permission.PACKAGE_USAGE_STATS
55     })
reportIncident(IncidentReportArgs args)56     public void reportIncident(IncidentReportArgs args) {
57         final IIncidentManager service = IIncidentManager.Stub.asInterface(
58                 ServiceManager.getService("incident"));
59         if (service == null) {
60             Slog.e(TAG, "reportIncident can't find incident binder service");
61             return;
62         }
63 
64         try {
65             service.reportIncident(args);
66         } catch (RemoteException ex) {
67             Slog.e(TAG, "reportIncident failed", ex);
68         }
69     }
70 
71     /**
72      * Convenience method to trigger an incident report and put it in dropbox.
73      * <p>
74      * The fields that are reported will be looked up in the system setting named by
75      * the settingName parameter.  The setting must match one of these patterns:
76      *      The string "disabled": The report will not be taken.
77      *      The string "all": The report will taken with all sections.
78      *      The string "none": The report will taken with no sections, but with the header.
79      *      A comma separated list of field numbers: The report will have these fields.
80      * <p>
81      * The header parameter will be added as a header for the incident report.  Fill in a
82      * {@link android.util.proto.ProtoOutputStream ProtoOutputStream}, and then call the
83      * {@link android.util.proto.ProtoOutputStream#bytes bytes()} method to retrieve
84      * the encoded data for the header.
85      */
86     @RequiresPermission(allOf = {
87             android.Manifest.permission.DUMP,
88             android.Manifest.permission.PACKAGE_USAGE_STATS
89     })
reportIncident(String settingName, byte[] headerProto)90     public void reportIncident(String settingName, byte[] headerProto) {
91         // Sections
92         String setting = Settings.System.getString(mContext.getContentResolver(), settingName);
93         IncidentReportArgs args;
94         try {
95             args = IncidentReportArgs.parseSetting(setting);
96         } catch (IllegalArgumentException ex) {
97             Slog.w(TAG, "Bad value for incident report setting '" + settingName + "'", ex);
98             return;
99         }
100         if (args == null) {
101             Slog.i(TAG, "Incident report requested but disabled: " + settingName);
102             return;
103         }
104 
105         // Header
106         args.addHeader(headerProto);
107 
108         // Look up the service
109         final IIncidentManager service = IIncidentManager.Stub.asInterface(
110                 ServiceManager.getService("incident"));
111         if (service == null) {
112             Slog.e(TAG, "reportIncident can't find incident binder service");
113             return;
114         }
115 
116         // Call the service
117         Slog.i(TAG, "Taking incident report: " + settingName);
118         try {
119             service.reportIncident(args);
120         } catch (RemoteException ex) {
121             Slog.e(TAG, "reportIncident failed", ex);
122         }
123     }
124 }
125 
126