OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.android_webview.crash; | 5 package org.chromium.android_webview.crash; |
6 | 6 |
7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
8 import android.app.Service; | 8 import android.app.Service; |
9 import android.app.job.JobInfo; | 9 import android.app.job.JobInfo; |
10 import android.app.job.JobScheduler; | 10 import android.app.job.JobScheduler; |
11 import android.content.ComponentName; | 11 import android.content.ComponentName; |
12 import android.content.Context; | 12 import android.content.Context; |
13 import android.content.Intent; | 13 import android.content.Intent; |
14 import android.os.Binder; | 14 import android.os.Binder; |
15 import android.os.Build; | 15 import android.os.Build; |
16 import android.os.IBinder; | 16 import android.os.IBinder; |
17 import android.os.ParcelFileDescriptor; | 17 import android.os.ParcelFileDescriptor; |
18 import android.webkit.ValueCallback; | |
18 | 19 |
20 import org.chromium.android_webview.PlatformServiceBridge; | |
21 import org.chromium.android_webview.command_line.CommandLineUtil; | |
19 import org.chromium.base.Log; | 22 import org.chromium.base.Log; |
20 import org.chromium.base.VisibleForTesting; | 23 import org.chromium.base.VisibleForTesting; |
21 import org.chromium.components.minidump_uploader.CrashFileManager; | 24 import org.chromium.components.minidump_uploader.CrashFileManager; |
22 | 25 |
23 import java.io.File; | 26 import java.io.File; |
24 import java.io.IOException; | 27 import java.io.IOException; |
25 import java.util.List; | 28 import java.util.List; |
26 | 29 |
27 /** | 30 /** |
28 * Service that is responsible for receiving crash dumps from an application, fo r upload. | 31 * Service that is responsible for receiving crash dumps from an application, fo r upload. |
29 */ | 32 */ |
30 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | 33 @TargetApi(Build.VERSION_CODES.LOLLIPOP) |
31 public class CrashReceiverService extends Service { | 34 public class CrashReceiverService extends Service { |
32 private static final String TAG = "CrashReceiverService"; | 35 private static final String TAG = "CrashReceiverService"; |
33 | 36 |
34 private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes"; | 37 private static final String WEBVIEW_CRASH_DIR = "WebView_Crashes"; |
35 private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp"; | 38 private static final String WEBVIEW_TMP_CRASH_DIR = "WebView_Crashes_Tmp"; |
36 | 39 |
37 private static final int MINIDUMP_UPLOADING_JOB_ID = 42; | 40 private static final int MINIDUMP_UPLOADING_JOB_ID = 42; |
38 // Initial back-off time for upload-job, this is set to a fairly high number (30 minutes) to | 41 // Initial back-off time for upload-job, this is set to a fairly high number (30 minutes) to |
39 // increase the chance of performing uploads in batches if the initial uploa d fails. | 42 // increase the chance of performing uploads in batches if the initial uploa d fails. |
40 private static final int JOB_BACKOFF_TIME_IN_MS = 1000 * 60 * 30; | 43 private static final int JOB_BACKOFF_TIME_IN_MS = 1000 * 60 * 30; |
41 // Back-off policy for upload-job. | 44 // Back-off policy for upload-job. |
42 private static final int JOB_BACKOFF_POLICY = JobInfo.BACKOFF_POLICY_EXPONEN TIAL; | 45 private static final int JOB_BACKOFF_POLICY = JobInfo.BACKOFF_POLICY_EXPONEN TIAL; |
43 | 46 |
44 private Object mCopyingLock = new Object(); | 47 private Object mCopyingLock = new Object(); |
45 private boolean mIsCopying = false; | 48 private boolean mIsCopying = false; |
46 | 49 |
47 // same switch as kEnableCrashReporterForTesting in //base/base_switches.h | 50 private static final int CONSENT_NOT_RETURNED = 0; |
48 static final String CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH = | 51 private static final int CONSENT_OK = 1; |
49 "enable-crash-reporter-for-testing"; | 52 private static final int CONSENT_NOT_OK = 2; |
53 | |
54 private Object mConsentLock = new Object(); | |
55 private int mConsentValueState = CONSENT_NOT_RETURNED; | |
sgurun-gerrit only
2017/01/24 08:58:49
nit: rename to mConsentValue
gsennton
2017/01/24 10:41:48
Done.
| |
56 | |
57 private void resetConsentState() { | |
58 synchronized (mConsentLock) { | |
59 mConsentValueState = CONSENT_NOT_RETURNED; | |
60 } | |
61 } | |
62 | |
63 private void setConsentValue(boolean ok) { | |
64 synchronized (mConsentLock) { | |
65 assert mConsentValueState == CONSENT_NOT_RETURNED; | |
66 mConsentValueState = ok ? CONSENT_OK : CONSENT_NOT_OK; | |
67 mConsentLock.notifyAll(); | |
68 } | |
69 } | |
70 | |
71 /** | |
72 * Wait until a consent value was received, and return that value. | |
73 */ | |
74 private boolean getConsentValue() { | |
sgurun-gerrit only
2017/01/24 08:58:49
would it be better to keep the methods that provid
gsennton
2017/01/24 10:41:47
Done.
| |
75 synchronized (mConsentLock) { | |
76 while (mConsentValueState == CONSENT_NOT_RETURNED) { | |
77 try { | |
78 mConsentLock.wait(); | |
79 } catch (InterruptedException e) { | |
80 break; | |
81 } | |
82 } | |
83 return mConsentValueState == CONSENT_OK; | |
84 } | |
85 } | |
50 | 86 |
51 @Override | 87 @Override |
52 public void onCreate() { | 88 public void onCreate() { |
53 super.onCreate(); | 89 super.onCreate(); |
54 SynchronizedWebViewCommandLine.initOnSeparateThread(); | 90 getSynchronizedWebViewCommandLine().initOnSeparateThread(); |
91 | |
92 resetConsentState(); | |
93 PlatformServiceBridge platformServiceBridge = getPlaformServiceBridge(); | |
94 if (platformServiceBridge.canUseGms()) { | |
95 platformServiceBridge.queryMetricsSetting(new ValueCallback<Boolean> () { | |
96 @Override | |
97 public void onReceiveValue(Boolean enabled) { | |
98 setConsentValue(enabled); | |
99 } | |
100 }); | |
101 } else { | |
102 setConsentValue(false); | |
103 } | |
104 } | |
105 | |
106 @VisibleForTesting | |
107 final boolean isCrashCopyingEnabled() { | |
108 if (getSynchronizedWebViewCommandLine().hasSwitch( | |
109 CommandLineUtil.CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH)) { | |
110 return true; | |
111 } | |
112 return getConsentValue(); | |
113 } | |
114 | |
115 @VisibleForTesting | |
116 SynchronizedWebViewCommandLine getSynchronizedWebViewCommandLine() { | |
117 return SynchronizedWebViewCommandLine.getInstance(); | |
118 } | |
119 | |
120 @VisibleForTesting | |
121 PlatformServiceBridge getPlaformServiceBridge() { | |
122 return PlatformServiceBridge.getInstance(this); | |
55 } | 123 } |
56 | 124 |
57 private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService .Stub() { | 125 private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService .Stub() { |
58 @Override | 126 @Override |
59 public void transmitCrashes(ParcelFileDescriptor[] fileDescriptors) { | 127 public void transmitCrashes(ParcelFileDescriptor[] fileDescriptors) { |
60 // TODO(gsennton): replace this check with a check for Android Check box when we have | 128 if (!isCrashCopyingEnabled()) { |
61 // access to that value through GmsCore. | |
62 if (!SynchronizedWebViewCommandLine.hasSwitch( | |
63 CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH)) { | |
64 Log.i(TAG, "Crash reporting is not enabled, bailing!"); | 129 Log.i(TAG, "Crash reporting is not enabled, bailing!"); |
65 return; | 130 return; |
66 } | 131 } |
132 | |
67 int uid = Binder.getCallingUid(); | 133 int uid = Binder.getCallingUid(); |
68 performMinidumpCopyingSerially( | 134 performMinidumpCopyingSerially( |
69 CrashReceiverService.this, uid, fileDescriptors, true /* sch eduleUploads */); | 135 CrashReceiverService.this, uid, fileDescriptors, true /* sch eduleUploads */); |
70 } | 136 } |
71 }; | 137 }; |
72 | 138 |
73 /** | 139 /** |
74 * Copies minidumps in a synchronized way, waiting for any already started c opying operations to | 140 * Copies minidumps in a synchronized way, waiting for any already started c opying operations to |
75 * finish before copying the current dumps. | 141 * finish before copying the current dumps. |
76 * @param scheduleUploads whether to ask JobScheduler to schedule an upload- job (avoid this | 142 * @param scheduleUploads whether to ask JobScheduler to schedule an upload- job (avoid this |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 @VisibleForTesting | 304 @VisibleForTesting |
239 public static File getWebViewTmpCrashDir(Context context) { | 305 public static File getWebViewTmpCrashDir(Context context) { |
240 return new File(context.getCacheDir(), WEBVIEW_TMP_CRASH_DIR); | 306 return new File(context.getCacheDir(), WEBVIEW_TMP_CRASH_DIR); |
241 } | 307 } |
242 | 308 |
243 @Override | 309 @Override |
244 public IBinder onBind(Intent intent) { | 310 public IBinder onBind(Intent intent) { |
245 return mBinder; | 311 return mBinder; |
246 } | 312 } |
247 } | 313 } |
OLD | NEW |