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.util.Slog;
25 
26 /**
27  * Class to take an incident report.
28  *
29  * @hide
30  */
31 @SystemApi
32 @TestApi
33 @SystemService(Context.INCIDENT_SERVICE)
34 public class IncidentManager {
35     private static final String TAG = "IncidentManager";
36 
37     private final Context mContext;
38 
39     private IIncidentManager mService;
40 
41     /**
42      * @hide
43      */
IncidentManager(Context context)44     public IncidentManager(Context context) {
45         mContext = context;
46     }
47 
48     /**
49      * Take an incident report and put it in dropbox.
50      */
51     @RequiresPermission(allOf = {
52             android.Manifest.permission.DUMP,
53             android.Manifest.permission.PACKAGE_USAGE_STATS
54     })
reportIncident(IncidentReportArgs args)55     public void reportIncident(IncidentReportArgs args) {
56         reportIncidentInternal(args);
57     }
58 
59     private class IncidentdDeathRecipient implements IBinder.DeathRecipient {
60         @Override
binderDied()61         public void binderDied() {
62             synchronized (this) {
63                 mService = null;
64             }
65         }
66     }
67 
reportIncidentInternal(IncidentReportArgs args)68     private void reportIncidentInternal(IncidentReportArgs args) {
69         try {
70             final IIncidentManager service = getIIncidentManagerLocked();
71             if (service == null) {
72                 Slog.e(TAG, "reportIncident can't find incident binder service");
73                 return;
74             }
75             service.reportIncident(args);
76         } catch (RemoteException ex) {
77             Slog.e(TAG, "reportIncident failed", ex);
78         }
79     }
80 
getIIncidentManagerLocked()81     private IIncidentManager getIIncidentManagerLocked() throws RemoteException {
82         if (mService != null) {
83             return mService;
84         }
85 
86         synchronized (this) {
87             if (mService != null) {
88                 return mService;
89             }
90             mService = IIncidentManager.Stub.asInterface(
91                 ServiceManager.getService(Context.INCIDENT_SERVICE));
92             if (mService != null) {
93                 mService.asBinder().linkToDeath(new IncidentdDeathRecipient(), 0);
94             }
95             return mService;
96         }
97     }
98 
99 }
100 
101