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
17package android.os;
18
19import android.annotation.RequiresPermission;
20import android.annotation.SystemApi;
21import android.annotation.SystemService;
22import android.annotation.TestApi;
23import android.content.Context;
24import 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)
34public 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     */
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    })
55    public void reportIncident(IncidentReportArgs args) {
56        reportIncidentInternal(args);
57    }
58
59    private class IncidentdDeathRecipient implements IBinder.DeathRecipient {
60        @Override
61        public void binderDied() {
62            synchronized (this) {
63                mService = null;
64            }
65        }
66    }
67
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
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