1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ImageInputTelemetry.h"
9 #include "mozilla/ContentEvents.h"
10 #include "mozilla/MouseEvents.h"
11 #include "mozilla/dom/Blob.h"
12 #include "mozilla/dom/DataTransfer.h"
13 #include "mozilla/dom/FileList.h"
14 #include "mozilla/glean/AntitrackingImageinputmetadatastripperMetrics.h"
15 #include "nsIPrincipal.h"
19 // Known MIME types as listed in nsMimeTypes.h + HEIC types
20 static constexpr nsLiteralCString kKnownImageMIMETypes
[] = {
28 "image/x-portable-pixmap"_ns
,
36 "image/x-ms-clipboard-bmp"_ns
,
38 "image/vnd.microsoft.icon"_ns
,
39 "image/icon"_ns
, // "video/x-mng"_ns, - This is checked in
40 // ImageInputTelemetry::IsKnownImageMIMEType()
46 // Additionally added HEIC image formats due to mobile popularity
51 /* private static */ bool ImageInputTelemetry::IsKnownImageMIMEType(
52 const nsCString
& aInputFileType
) {
53 if (aInputFileType
.Find("video/x-mng"_ns
) != kNotFound
) {
56 if (aInputFileType
.Find("image/"_ns
) != kNotFound
) {
57 for (const nsCString
& knownImageMIMEType
: kKnownImageMIMETypes
) {
58 if (aInputFileType
.Equals(knownImageMIMEType
)) {
66 /* private static */ bool ImageInputTelemetry::IsContentPrincipal(
67 nsIPrincipal
* aContentPrincipal
) {
68 bool isSystemPrincipal
;
69 aContentPrincipal
->GetIsSystemPrincipal(&isSystemPrincipal
);
70 return !(isSystemPrincipal
|| aContentPrincipal
->SchemeIs("about"));
73 /* private static */ void ImageInputTelemetry::RecordImageInputTelemetry(
74 const nsCString
& aImageType
, ImageInputType aInputType
) {
75 nsAutoCString inputType
;
77 case ImageInputType::Drop
:
78 inputType
= "Drop"_ns
;
80 case ImageInputType::Paste
:
81 inputType
= "Paste"_ns
;
83 case ImageInputType::FilePicker
:
84 inputType
= "FilePicker"_ns
;
87 glean::image_input_telemetry::ImageInputExtra extra
= {
88 .imageType
= Some(aImageType
),
89 .inputType
= Some(inputType
),
91 glean::image_input_telemetry::image_input
.Record(Some(extra
));
94 /* private static */ void ImageInputTelemetry::MaybeRecordImageInputTelemetry(
95 ImageInputType aInputType
, dom::DataTransfer
* aDataTransfer
) {
96 // Check if input datatransfers contains files.
97 RefPtr
<dom::FileList
> files
=
98 aDataTransfer
->GetFiles(*nsContentUtils::GetSystemPrincipal());
103 nsAutoString fileType
;
105 for (uint32_t i
= 0; i
< files
->Length(); i
++) {
106 dom::File
* file
= files
->Item(i
);
111 file
->GetType(fileType
);
112 fileTypeC
= NS_ConvertUTF16toUTF8(fileType
);
113 if (IsKnownImageMIMEType(fileTypeC
)) {
114 ImageInputTelemetry::RecordImageInputTelemetry(fileTypeC
, aInputType
);
119 /* static */ void ImageInputTelemetry::MaybeRecordDropImageInputTelemetry(
120 WidgetDragEvent
* aDragEvent
, nsIPrincipal
* aContentPrincipal
) {
121 MOZ_ASSERT(aDragEvent
);
122 MOZ_ASSERT(aContentPrincipal
);
124 // Only collect telemetry when drag data is accessed on drop.
125 if (aDragEvent
->mMessage
!= eDrop
|| !aDragEvent
->mDataTransfer
) {
129 // Only process events on content, not about pages, e.g. default drop
130 // handler displays dropped file.
131 if (!IsContentPrincipal(aContentPrincipal
)) {
135 ImageInputTelemetry::MaybeRecordImageInputTelemetry(
136 ImageInputType::Drop
, aDragEvent
->mDataTransfer
);
139 /* static */ void ImageInputTelemetry::MaybeRecordPasteImageInputTelemetry(
140 InternalClipboardEvent
* aClipboardEvent
, nsIPrincipal
* aContentPrincipal
) {
141 MOZ_ASSERT(aClipboardEvent
);
142 MOZ_ASSERT(aContentPrincipal
);
144 // Only collect telemetry when clipboard data is accessed on paste.
145 if (aClipboardEvent
->mMessage
!= ePaste
|| !aClipboardEvent
->mClipboardData
) {
149 // Only process events on content, neither system (e.g. URL bar) nor
150 // about pages (e.g. searchbar in about:preferences).
151 if (!IsContentPrincipal(aContentPrincipal
)) {
155 ImageInputTelemetry::MaybeRecordImageInputTelemetry(
156 ImageInputType::Paste
, aClipboardEvent
->mClipboardData
);
159 /* static */ void ImageInputTelemetry::MaybeRecordFilePickerImageInputTelemetry(
160 dom::Blob
* aFilePickerBlob
) {
161 MOZ_ASSERT(aFilePickerBlob
);
163 nsAutoString fileType
;
165 aFilePickerBlob
->GetType(fileType
);
166 fileTypeC
= NS_ConvertUTF16toUTF8(fileType
);
167 if (IsKnownImageMIMEType(fileTypeC
)) {
168 ImageInputTelemetry::RecordImageInputTelemetry(fileTypeC
,
169 ImageInputType::FilePicker
);
173 } // namespace mozilla