зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1879154) for causing bustage on nsUserCharacteristics.h. CLOSED TREE
Backed out changeset 62b681084f12 (bug 1879154) Backed out changeset 0673192f62c4 (bug 1879154) Backed out changeset 49bd1eba2ef6 (bug 1879154) Backed out changeset 254b5503de48 (bug 1879154)
This commit is contained in:
Родитель
19891da370
Коммит
2df76493a7
|
@ -621,19 +621,6 @@ pref("toolkit.telemetry.dap_helper", "https://dap.services.mozilla.com");
|
|||
pref("toolkit.telemetry.dap_helper_owner", "Mozilla");
|
||||
pref("toolkit.telemetry.dap.logLevel", "Warn");
|
||||
|
||||
// pref for mozilla to induce a new ping from users. This value should only ever be increased
|
||||
// and doing so will induce a new data ping from all users, so be careful. Mozilla may edit
|
||||
// this pref via our remote update/experimentation system
|
||||
pref("toolkit.telemetry.user_characteristics_ping.current_version", 0);
|
||||
// pref containing the value for the user of the last version of the ping we sent
|
||||
// if a user wants to disable this type of ping explicitly, set this to -1
|
||||
// firefox/mozilla will not modify this value if a negative number is present.
|
||||
pref("toolkit.telemetry.user_characteristics_ping.last_version_sent", 0);
|
||||
// A unique identifier for the user characteristics ping. This is not the same as
|
||||
// the telemetry client id (which is not sent in this ping), it is cleared when a
|
||||
// user opts-out of telemetry, it is set upon first telemetry submission
|
||||
pref("toolkit.telemetry.user_characteristics_ping.uuid", "");
|
||||
|
||||
// AsyncShutdown delay before crashing in case of shutdown freeze
|
||||
// ASan, TSan and code coverage builds can be considerably slower. Extend the
|
||||
// grace period for both the asyncshutdown and the terminator.
|
||||
|
|
|
@ -124,7 +124,6 @@ firefox_desktop_pings = [
|
|||
"browser/components/search/pings.yaml",
|
||||
"browser/components/urlbar/pings.yaml",
|
||||
"toolkit/components/crashes/pings.yaml",
|
||||
"toolkit/components/resistfingerprinting/pings.yaml",
|
||||
"toolkit/components/telemetry/pings.yaml",
|
||||
"toolkit/modules/pings.yaml",
|
||||
]
|
||||
|
|
|
@ -25,48 +25,3 @@ fingerprinting.protection:
|
|||
- tschuster@mozilla.com
|
||||
expires: never
|
||||
telemetry_mirror: FINGERPRINTING_PROTECTION_CANVAS_NOISE_CALCULATE_TIME_MS
|
||||
|
||||
|
||||
characteristics:
|
||||
client_identifier:
|
||||
type: uuid
|
||||
description: >
|
||||
A unique identifier for a user, not the same as the normal Telemetry
|
||||
client_id, but needed so we can deduplicate reports and only take the most
|
||||
recent one per user.
|
||||
lifetime: application
|
||||
send_in_pings:
|
||||
- user-characteristics
|
||||
- deletion-request
|
||||
notification_emails:
|
||||
- tom@mozilla.com
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879151
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879154
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879154#c8
|
||||
expires: never
|
||||
data_sensitivity:
|
||||
- technical
|
||||
|
||||
submission_schema:
|
||||
type: quantity
|
||||
unit: versions
|
||||
description: >
|
||||
An incrementing constant that represents the current schema/source of the
|
||||
data present in a ping. By referring to this value in a ping, one can know
|
||||
for certain the provenance of other data present in the ping, and what
|
||||
data may or may not be present.
|
||||
lifetime: application
|
||||
send_in_pings:
|
||||
- user-characteristics
|
||||
notification_emails:
|
||||
- tom@mozilla.com
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879151
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879154
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879154#c8
|
||||
expires: never
|
||||
data_sensitivity:
|
||||
- technical
|
||||
|
|
|
@ -11,7 +11,6 @@ TEST_DIRS += ["tests"]
|
|||
|
||||
UNIFIED_SOURCES += [
|
||||
"nsRFPService.cpp",
|
||||
"nsUserCharacteristics.cpp",
|
||||
"RelativeTimeline.cpp",
|
||||
]
|
||||
|
||||
|
@ -24,7 +23,6 @@ EXPORTS.mozilla += [
|
|||
"RelativeTimeline.h",
|
||||
"RFPTargetIPCUtils.h",
|
||||
]
|
||||
EXPORTS.mozilla.gtest += ["nsUserCharacteristics.h"]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
"FingerprintingWebCompatService.sys.mjs",
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
#include "nsTLiteralString.h"
|
||||
#include "nsTPromiseFlatString.h"
|
||||
#include "nsTStringRepr.h"
|
||||
#include "nsUserCharacteristics.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
#include "nsICookieJarSettings.h"
|
||||
|
@ -101,13 +100,8 @@ static mozilla::LazyLogModule gFingerprinterDetection("FingerprinterDetection");
|
|||
|
||||
#define RESIST_FINGERPRINTINGPROTECTION_OVERRIDE_PREF \
|
||||
"privacy.fingerprintingProtection.overrides"
|
||||
#define GLEAN_DATA_SUBMISSION_PREF "datareporting.healthreport.uploadEnabled"
|
||||
#define USER_CHARACTERISTICS_UUID_PREF \
|
||||
"toolkit.telemetry.user_characteristics_ping.uuid"
|
||||
|
||||
#define RFP_TIMER_UNCONDITIONAL_VALUE 20
|
||||
#define LAST_PB_SESSION_EXITED_TOPIC "last-pb-context-exited"
|
||||
#define IDLE_TOPIC "browser-idle-startup-tasks-finished"
|
||||
|
||||
static constexpr uint32_t kVideoFramesPerSec = 30;
|
||||
static constexpr uint32_t kVideoDroppedRatio = 5;
|
||||
|
@ -162,7 +156,6 @@ already_AddRefed<nsRFPService> nsRFPService::GetOrCreate() {
|
|||
|
||||
static const char* gCallbackPrefs[] = {
|
||||
RESIST_FINGERPRINTINGPROTECTION_OVERRIDE_PREF,
|
||||
GLEAN_DATA_SUBMISSION_PREF,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
|
@ -183,9 +176,6 @@ nsresult nsRFPService::Init() {
|
|||
|
||||
rv = obs->AddObserver(this, OBSERVER_TOPIC_IDLE_DAILY, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = obs->AddObserver(this, IDLE_TOPIC, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
Preferences::RegisterCallbacks(nsRFPService::PrefChanged, gCallbackPrefs,
|
||||
|
@ -283,7 +273,6 @@ void nsRFPService::StartShutdown() {
|
|||
if (XRE_IsParentProcess()) {
|
||||
obs->RemoveObserver(this, LAST_PB_SESSION_EXITED_TOPIC);
|
||||
obs->RemoveObserver(this, OBSERVER_TOPIC_IDLE_DAILY);
|
||||
obs->RemoveObserver(this, IDLE_TOPIC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,21 +290,10 @@ void nsRFPService::PrefChanged(const char* aPref, void* aSelf) {
|
|||
}
|
||||
|
||||
void nsRFPService::PrefChanged(const char* aPref) {
|
||||
MOZ_LOG(gResistFingerprintingLog, LogLevel::Info,
|
||||
("Pref Changed: %s", aPref));
|
||||
nsDependentCString pref(aPref);
|
||||
|
||||
if (pref.EqualsLiteral(RESIST_FINGERPRINTINGPROTECTION_OVERRIDE_PREF)) {
|
||||
UpdateFPPOverrideList();
|
||||
} else if (pref.EqualsLiteral(GLEAN_DATA_SUBMISSION_PREF)) {
|
||||
if (XRE_IsParentProcess() &&
|
||||
!Preferences::GetBool(GLEAN_DATA_SUBMISSION_PREF, false)) {
|
||||
MOZ_LOG(gResistFingerprintingLog, LogLevel::Info, ("Clearing UUID"));
|
||||
// If the user has unset the telemetry pref, wipe out the UUID pref value
|
||||
// (The data will also be erased server-side via the "deletion-request"
|
||||
// ping)
|
||||
Preferences::SetCString(USER_CHARACTERISTICS_UUID_PREF, ""_ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,10 +312,6 @@ nsRFPService::Observe(nsISupports* aObject, const char* aTopic,
|
|||
ClearBrowsingSessionKey(pattern);
|
||||
}
|
||||
|
||||
if (!strcmp(IDLE_TOPIC, aTopic)) {
|
||||
nsUserCharacteristics::MaybeSubmitPing();
|
||||
}
|
||||
|
||||
if (!strcmp(OBSERVER_TOPIC_IDLE_DAILY, aTopic)) {
|
||||
if (StaticPrefs::
|
||||
privacy_resistFingerprinting_randomization_daily_reset_enabled()) {
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsUserCharacteristics.h"
|
||||
|
||||
#include "nsID.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/glean/GleanPings.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
|
||||
static mozilla::LazyLogModule gUserCharacteristicsLog("UserCharacteristics");
|
||||
|
||||
// The current schema of the data. Anytime you add a metric, or change how a
|
||||
// metric is set, this variable should be incremented. It'll be a lot. It's
|
||||
// okay. We're going to need it to know (including during development) what is
|
||||
// the source of the data we are looking at.
|
||||
const int kSubmissionSchema = 0;
|
||||
|
||||
/* static */
|
||||
void nsUserCharacteristics::MaybeSubmitPing() {
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Debug, ("In MaybeSubmitPing()"));
|
||||
|
||||
/**
|
||||
* There are two preferences at play here:
|
||||
* - Last Version Sent - preference containing the last version sent by the
|
||||
* user to Mozilla
|
||||
* - Current Version - preference containing the version Mozilla would like
|
||||
* the user to send
|
||||
*
|
||||
* A point of complexity arises in that these two values _may_ be changed
|
||||
* by the user, even though neither is intended to be.
|
||||
*
|
||||
* When Current Version > Last Version Sent, we intend for the user to submit
|
||||
* a new ping, which will include the schema version. Then update Last Version
|
||||
* Sent = Current Version.
|
||||
*
|
||||
*/
|
||||
const auto* const kLastVersionPref =
|
||||
"toolkit.telemetry.user_characteristics_ping.last_version_sent";
|
||||
const auto* const kCurrentVersionPref =
|
||||
"toolkit.telemetry.user_characteristics_ping.current_version";
|
||||
|
||||
auto lastSubmissionVersion = Preferences::GetInt(kLastVersionPref, 0);
|
||||
auto currentVersion = Preferences::GetInt(kCurrentVersionPref, 0);
|
||||
|
||||
MOZ_ASSERT(currentVersion == -1 || lastSubmissionVersion <= currentVersion,
|
||||
"lastSubmissionVersion is somehow greater than currentVersion "
|
||||
"- did you edit prefs improperly?");
|
||||
|
||||
if (lastSubmissionVersion < 0) {
|
||||
// This is a way for users to opt out of this ping specifically.
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Debug,
|
||||
("Returning, User Opt-out"));
|
||||
return;
|
||||
}
|
||||
if (currentVersion == 0) {
|
||||
// Do nothing. We do not want any pings.
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Debug,
|
||||
("Returning, currentVersion == 0"));
|
||||
return;
|
||||
}
|
||||
if (currentVersion == -1) {
|
||||
// currentVersion = -1 is a development value to force a ping submission
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Debug,
|
||||
("Force-Submitting Ping"));
|
||||
if (NS_SUCCEEDED(PopulateData())) {
|
||||
SubmitPing();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (lastSubmissionVersion > currentVersion) {
|
||||
// This is an unexpected scneario that indicates something is wrong. We
|
||||
// asserted against it (in debug, above) We will try to sanity-correct
|
||||
// ourselves by setting it to the current version.
|
||||
Preferences::SetInt(kLastVersionPref, currentVersion);
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Warning,
|
||||
("Returning, lastSubmissionVersion > currentVersion"));
|
||||
return;
|
||||
}
|
||||
if (lastSubmissionVersion == currentVersion) {
|
||||
// We are okay, we've already submitted the most recent ping
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Warning,
|
||||
("Returning, lastSubmissionVersion == currentVersion"));
|
||||
return;
|
||||
}
|
||||
if (lastSubmissionVersion < currentVersion) {
|
||||
if (NS_SUCCEEDED(PopulateData())) {
|
||||
if (NS_SUCCEEDED(SubmitPing())) {
|
||||
Preferences::SetInt(kLastVersionPref, currentVersion);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Should never reach here");
|
||||
}
|
||||
}
|
||||
|
||||
const auto* const kUUIDPref =
|
||||
"toolkit.telemetry.user_characteristics_ping.uuid";
|
||||
|
||||
/* static */
|
||||
nsresult nsUserCharacteristics::PopulateData() {
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Warning, ("Populating Data"));
|
||||
mozilla::glean::characteristics::submission_schema.Set(kSubmissionSchema);
|
||||
|
||||
nsAutoCString uuidString;
|
||||
nsresult rv = Preferences::GetCString(kUUIDPref, uuidString);
|
||||
if (NS_FAILED(rv) || uuidString.Length() == 0) {
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIDToCString id(nsID::GenerateUUID());
|
||||
uuidString = id.get();
|
||||
Preferences::SetCString(kUUIDPref, uuidString);
|
||||
}
|
||||
mozilla::glean::characteristics::client_identifier.Set(uuidString);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult nsUserCharacteristics::SubmitPing() {
|
||||
MOZ_LOG(gUserCharacteristicsLog, LogLevel::Warning, ("Submitting Ping"));
|
||||
mozilla::glean_pings::UserCharacteristics.Submit();
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsUserCharacteristics_h__
|
||||
#define __nsUserCharacteristics_h__
|
||||
|
||||
class nsUserCharacteristics {
|
||||
public:
|
||||
static void MaybeSubmitPing();
|
||||
|
||||
// Public For testing
|
||||
static nsresult PopulateData();
|
||||
static nsresult SubmitPing();
|
||||
};
|
||||
#endif /* __nsUserCharacteristics_h__ */
|
|
@ -1,19 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
---
|
||||
$schema: moz://mozilla.org/schemas/glean/pings/2-0-0
|
||||
|
||||
user-characteristics:
|
||||
description: |
|
||||
A ping representing user hardware and software settings. Note that this
|
||||
ping does not include client_id. More details are available in Bug 1879151
|
||||
include_client_id: false
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879151
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879154
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1879154#c8
|
||||
notification_emails:
|
||||
- tritter@mozilla.com
|
|
@ -1,6 +1,5 @@
|
|||
UNIFIED_SOURCES += [
|
||||
"test_reduceprecision.cpp",
|
||||
"test_usercharping.cpp",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul-gtest"
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/gtest/nsUserCharacteristics.h"
|
||||
|
||||
#include "mozilla/glean/GleanPings.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
const auto* const kUUIDPref =
|
||||
"toolkit.telemetry.user_characteristics_ping.uuid";
|
||||
|
||||
TEST(ResistFingerprinting, UserCharacteristics_Simple)
|
||||
{
|
||||
bool submitted = false;
|
||||
mozilla::glean_pings::UserCharacteristics.TestBeforeNextSubmit(
|
||||
[&submitted](const nsACString& aReason) {
|
||||
submitted = true;
|
||||
});
|
||||
mozilla::glean_pings::UserCharacteristics.Submit();
|
||||
ASSERT_TRUE(submitted);
|
||||
}
|
||||
|
||||
TEST(ResistFingerprinting, UserCharacteristics_Complex)
|
||||
{
|
||||
nsUserCharacteristics::PopulateData();
|
||||
|
||||
bool submitted = false;
|
||||
mozilla::glean_pings::UserCharacteristics.TestBeforeNextSubmit(
|
||||
[&submitted](const nsACString& aReason) {
|
||||
submitted = true;
|
||||
|
||||
ASSERT_STRNE("", mozilla::glean::characteristics::client_identifier
|
||||
.TestGetValue()
|
||||
.unwrap()
|
||||
.value()
|
||||
.get());
|
||||
|
||||
nsCString fullUuidStr;
|
||||
Preferences::GetCString(kUUIDPref, fullUuidStr);
|
||||
|
||||
// Remove the '{' and '}'
|
||||
nsAutoCString uuidString;
|
||||
uuidString = Substring(fullUuidStr, 1, NSID_LENGTH - 3);
|
||||
|
||||
ASSERT_STREQ(
|
||||
uuidString.get(),
|
||||
mozilla::glean::characteristics::client_identifier.TestGetValue()
|
||||
.unwrap()
|
||||
.value()
|
||||
.get());
|
||||
});
|
||||
nsUserCharacteristics::SubmitPing();
|
||||
ASSERT_TRUE(submitted);
|
||||
}
|
||||
|
||||
TEST(ResistFingerprinting, UserCharacteristics_ClearPref)
|
||||
{
|
||||
nsCString originalUUID;
|
||||
|
||||
mozilla::glean_pings::UserCharacteristics.TestBeforeNextSubmit(
|
||||
[&originalUUID](const nsACString& aReason) {
|
||||
originalUUID =
|
||||
mozilla::glean::characteristics::client_identifier.TestGetValue()
|
||||
.unwrap()
|
||||
.value()
|
||||
.get();
|
||||
ASSERT_STRNE("", mozilla::glean::characteristics::client_identifier
|
||||
.TestGetValue()
|
||||
.unwrap()
|
||||
.value()
|
||||
.get());
|
||||
|
||||
nsCString fullUuidStr;
|
||||
Preferences::GetCString(kUUIDPref, fullUuidStr);
|
||||
|
||||
// Remove the '{' and '}'
|
||||
nsAutoCString uuidString;
|
||||
uuidString = Substring(fullUuidStr, 1, NSID_LENGTH - 3);
|
||||
|
||||
ASSERT_STREQ(
|
||||
uuidString.get(),
|
||||
mozilla::glean::characteristics::client_identifier.TestGetValue()
|
||||
.unwrap()
|
||||
.value()
|
||||
.get());
|
||||
});
|
||||
nsUserCharacteristics::PopulateData();
|
||||
nsUserCharacteristics::SubmitPing();
|
||||
|
||||
auto original_value =
|
||||
Preferences::GetBool("datareporting.healthreport.uploadEnabled");
|
||||
Preferences::SetBool("datareporting.healthreport.uploadEnabled", true);
|
||||
Preferences::SetBool("datareporting.healthreport.uploadEnabled", false);
|
||||
|
||||
mozilla::glean_pings::UserCharacteristics.TestBeforeNextSubmit(
|
||||
[](const nsACString& aReason) {
|
||||
// Assert that the pref is blank
|
||||
nsAutoCString uuidValue;
|
||||
Preferences::GetCString(kUUIDPref, uuidValue);
|
||||
ASSERT_STREQ("", uuidValue.get());
|
||||
});
|
||||
nsUserCharacteristics::SubmitPing();
|
||||
|
||||
Preferences::SetBool("datareporting.healthreport.uploadEnabled", true);
|
||||
mozilla::glean_pings::UserCharacteristics.TestBeforeNextSubmit(
|
||||
[&originalUUID](const nsACString& aReason) {
|
||||
// Assert that the new UUID is different from the old one
|
||||
ASSERT_STRNE(
|
||||
originalUUID.get(),
|
||||
mozilla::glean::characteristics::client_identifier.TestGetValue()
|
||||
.unwrap()
|
||||
.value()
|
||||
.get());
|
||||
|
||||
// Assert that the pref is not blank
|
||||
nsAutoCString uuidValue;
|
||||
Preferences::GetCString(kUUIDPref, uuidValue);
|
||||
ASSERT_STRNE("", uuidValue.get());
|
||||
});
|
||||
nsUserCharacteristics::PopulateData();
|
||||
nsUserCharacteristics::SubmitPing();
|
||||
|
||||
Preferences::SetBool("datareporting.healthreport.uploadEnabled",
|
||||
original_value);
|
||||
}
|
Загрузка…
Ссылка в новой задаче