• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.backup.utils;
18 
19 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_AGENT_LOGGING_RESULTS;
20 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
21 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE;
22 import static android.app.backup.BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT;
23 import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_AGENT_LOGGING_RESULTS;
24 
25 import static com.android.server.backup.BackupManagerService.TAG;
26 
27 import android.annotation.Nullable;
28 import android.app.IBackupAgent;
29 import android.app.backup.BackupAnnotations.OperationType;
30 import android.app.backup.BackupManagerMonitor;
31 import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
32 import android.app.backup.IBackupManagerMonitor;
33 import android.content.pm.PackageInfo;
34 import android.os.Bundle;
35 import android.os.RemoteException;
36 import android.util.Slog;
37 
38 import com.android.internal.annotations.VisibleForTesting;
39 import com.android.internal.infra.AndroidFuture;
40 
41 import java.util.List;
42 import java.util.concurrent.TimeUnit;
43 import java.util.concurrent.TimeoutException;
44 
45 /**
46  * Utility methods to log BackupManagerMonitor events.
47  */
48 public class BackupManagerMonitorEventSender {
49     /**
50      * Timeout for how long we wait before we give up on getting logs from a {@link IBackupAgent}.
51      * We expect this to be very fast since the agent immediately returns whatever logs have been
52      * accumulated. The timeout adds a bit more security and ensures we don't hang the B&R waiting
53      * for non-essential logs.
54      */
55     private static final int AGENT_LOGGER_RESULTS_TIMEOUT_MILLIS = 500;
56     @Nullable private IBackupManagerMonitor mMonitor;
57     private final BackupManagerMonitorDumpsysUtils mBackupManagerMonitorDumpsysUtils;
BackupManagerMonitorEventSender(@ullable IBackupManagerMonitor monitor)58     public BackupManagerMonitorEventSender(@Nullable IBackupManagerMonitor monitor) {
59         mMonitor = monitor;
60         mBackupManagerMonitorDumpsysUtils = new BackupManagerMonitorDumpsysUtils();
61     }
62 
63     @VisibleForTesting
BackupManagerMonitorEventSender(@ullable IBackupManagerMonitor monitor, BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils)64     BackupManagerMonitorEventSender(@Nullable IBackupManagerMonitor monitor,
65             BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils) {
66         mMonitor = monitor;
67         mBackupManagerMonitorDumpsysUtils = backupManagerMonitorDumpsysUtils;
68     }
69 
setMonitor(IBackupManagerMonitor monitor)70     public void setMonitor(IBackupManagerMonitor monitor) {
71         mMonitor = monitor;
72     }
73 
74     @Nullable
getMonitor()75     public IBackupManagerMonitor getMonitor() {
76         return mMonitor;
77     }
78 
79     /**
80      * Notifies monitor about the event.
81      *
82      * Calls {@link IBackupManagerMonitor#onEvent(Bundle)} with a bundle representing current event.
83      *
84      * @param id - event id.
85      * @param pkg - package event is related to.
86      * @param category - event category.
87      * @param extras - additional event data.
88      */
monitorEvent( int id, @Nullable PackageInfo pkg, int category, @Nullable Bundle extras)89     public void monitorEvent(
90             int id,
91             @Nullable PackageInfo pkg,
92             int category,
93             @Nullable Bundle extras) {
94         try {
95             Bundle bundle = new Bundle();
96             bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID, id);
97             bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY, category);
98             if (pkg != null) {
99                 bundle.putString(EXTRA_LOG_EVENT_PACKAGE_NAME,
100                         pkg.packageName);
101                 bundle.putInt(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION,
102                         pkg.versionCode);
103                 bundle.putLong(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION,
104                         pkg.getLongVersionCode());
105             }
106             if (extras != null) {
107                 bundle.putAll(extras);
108                 if (extras.containsKey(EXTRA_LOG_OPERATION_TYPE) &&
109                         extras.getInt(EXTRA_LOG_OPERATION_TYPE) == OperationType.RESTORE){
110                     mBackupManagerMonitorDumpsysUtils
111                             .parseBackupManagerMonitorRestoreEventForDumpsys(bundle);
112                 }
113             }
114 
115             if (mMonitor != null) {
116                 mMonitor.onEvent(bundle);
117             } else {
118                 Slog.w(TAG, "backup manager monitor is null unable to send event");
119             }
120         } catch (RemoteException e) {
121             mMonitor = null;
122             Slog.w(TAG, "backup manager monitor went away");
123         }
124     }
125 
126     /**
127      * Extracts logging results from the provided {@code agent} and notifies the {@code monitor}
128      * about them.
129      *
130      * <p>Note that this method does two separate binder calls (one to the agent and one to the
131      * monitor).
132      *
133      * @param pkg - package the {@code agent} belongs to.
134      * @param agent - the {@link IBackupAgent} to retrieve logs from.
135      */
monitorAgentLoggingResults(PackageInfo pkg, IBackupAgent agent)136     public void monitorAgentLoggingResults(PackageInfo pkg, IBackupAgent agent) {
137         if (mMonitor == null) {
138             Slog.i(TAG, "backup manager monitor is null unable to send event"+pkg);
139         }
140 
141         try {
142             AndroidFuture<List<DataTypeResult>> resultsFuture =
143                     new AndroidFuture<>();
144             AndroidFuture<Integer> operationTypeFuture = new AndroidFuture<>();
145             agent.getLoggerResults(resultsFuture);
146             agent.getOperationType(operationTypeFuture);
147             sendAgentLoggingResults(pkg,
148                     resultsFuture.get(AGENT_LOGGER_RESULTS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS),
149                     operationTypeFuture.get(AGENT_LOGGER_RESULTS_TIMEOUT_MILLIS,
150                             TimeUnit.MILLISECONDS));
151         } catch (TimeoutException e) {
152             Slog.w(TAG, "Timeout while waiting to retrieve logging results from agent", e);
153         } catch (Exception e) {
154             Slog.w(TAG, "Failed to retrieve logging results from agent", e);
155         }
156     }
157 
sendAgentLoggingResults(PackageInfo pkg, List<DataTypeResult> results, @OperationType int operationType)158     public void sendAgentLoggingResults(PackageInfo pkg, List<DataTypeResult> results,
159             @OperationType int operationType) {
160         Bundle loggerResultsBundle = new Bundle();
161         loggerResultsBundle.putParcelableList(
162                 EXTRA_LOG_AGENT_LOGGING_RESULTS, results);
163         loggerResultsBundle.putInt(EXTRA_LOG_OPERATION_TYPE, operationType);
164         monitorEvent(
165                 LOG_EVENT_ID_AGENT_LOGGING_RESULTS,
166                 pkg,
167                 LOG_EVENT_CATEGORY_AGENT,
168                 loggerResultsBundle);
169     }
170 
171     /**
172      * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
173      * be created.
174      *
175      * @param extras - bundle where to add key-value to, if null a new bundle will be created.
176      * @param key - key.
177      * @param value - value.
178      * @return extras if it was not null and new bundle otherwise.
179      */
putMonitoringExtra(Bundle extras, String key, String value)180     public static Bundle putMonitoringExtra(Bundle extras, String key, String value) {
181         if (extras == null) {
182             extras = new Bundle();
183         }
184         extras.putString(key, value);
185         return extras;
186     }
187 
188     /**
189      * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
190      * be created.
191      *
192      * @param extras - bundle where to add key-value to, if null a new bundle will be created.
193      * @param key - key.
194      * @param value - value.
195      * @return extras if it was not null and new bundle otherwise.
196      */
putMonitoringExtra(Bundle extras, String key, long value)197     public static Bundle putMonitoringExtra(Bundle extras, String key, long value) {
198         if (extras == null) {
199             extras = new Bundle();
200         }
201         extras.putLong(key, value);
202         return extras;
203     }
204 
205     /**
206      * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
207      * be created.
208      *
209      * @param extras - bundle where to add key-value to, if null a new bundle will be created.
210      * @param key - key.
211      * @param value - value.
212      * @return extras if it was not null and new bundle otherwise.
213      */
putMonitoringExtra(Bundle extras, String key, boolean value)214     public static Bundle putMonitoringExtra(Bundle extras, String key, boolean value) {
215         if (extras == null) {
216             extras = new Bundle();
217         }
218         extras.putBoolean(key, value);
219         return extras;
220     }
221 
222     /**
223      * Adds given key-value pair in the bundle and returns the bundle. If bundle was null it will
224      * be created.
225      *
226      * @param extras - bundle where to add key-value to, if null a new bundle will be created.
227      * @param key - key.
228      * @param value - value.
229      * @return extras if it was not null and new bundle otherwise.
230      */
putMonitoringExtra(Bundle extras, String key, int value)231     public static Bundle putMonitoringExtra(Bundle extras, String key, int value) {
232         if (extras == null) {
233             extras = new Bundle();
234         }
235         extras.putInt(key, value);
236         return extras;
237     }
238 }
239