Chromium Code Reviews| 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 |