[Net] Add Java version of NetworkTrafficAnnotationTag
This class is very similar to the C++ NetworkTrafficAnnotationTag class. It requires the same kind of documentation, in as a text protobuf. As a proof-of-concept, update EndpointFetcher methods to take a NetworkTrafficAnnotationTag argument, and plumb it down to C++. For now, use NO_TRAFFIC_ANNOTATION_YET in callers. Since auditor.py doesn't scan Java files yet, the contents of the annotations doesn't need to be valid for now. Bug: 1231780, 995852 Change-Id: I798a99adfd9d2d2afee537b78d379e9f05b49a9a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3045770 Reviewed-by: David Trainor <dtrainor@chromium.org> Reviewed-by: Ryan Sleevi <rsleevi@chromium.org> Reviewed-by: Andrew Grieve <agrieve@chromium.org> Reviewed-by: Wei-Yin Chen (陳威尹) <wychen@chromium.org> Reviewed-by: Ramin Halavati <rhalavati@chromium.org> Commit-Queue: Nicolas Ouellet-Payeur <nicolaso@chromium.org> Cr-Commit-Position: refs/heads/main@{#917776}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b03a695762
commit
e8bcd6f751
chrome
android
features
tab_ui
BUILD.gn
java
src
org
chromium
chrome
browser
tasks
tab_management
suggestions
junit
src
org
chromium
chrome
browser
tasks
tab_management
javatests
src
org
chromium
chrome
browser
commerce
subscriptions
android
java
src
org
chromium
chrome
browser
subscriptions
test
android
java
src
org
chromium
chrome
browser
subscriptions
endpoint_fetcher
page_annotations
android
test
android
tab
java
src
org
chromium
chrome
browser
tab
net
tools/traffic_annotation/auditor
@ -233,6 +233,7 @@ android_library("java") {
|
||||
"//components/site_engagement/content/android:java",
|
||||
"//content/public/android:content_java",
|
||||
"//content/public/android:content_java_resources",
|
||||
"//net/android:net_java",
|
||||
"//third_party/android_deps:android_support_v7_appcompat_java",
|
||||
"//third_party/android_deps:material_design_java",
|
||||
"//third_party/androidx:androidx_annotation_annotation_java",
|
||||
|
@ -21,6 +21,7 @@ import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
|
||||
import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
|
||||
import org.chromium.components.signin.identitymanager.ConsentLevel;
|
||||
import org.chromium.net.NetworkTrafficAnnotationTag;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
@ -78,12 +79,14 @@ public class TabSuggestionsServerFetcher implements TabSuggestionsFetcher {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// TODO(crbug.com/995852): Replace NO_TRAFFIC_ANNOTATION_YET with a real traffic
|
||||
// annotation.
|
||||
EndpointFetcher.fetchUsingChromeAPIKey(res
|
||||
-> { fetchCallback(res, callback, tabContext); },
|
||||
mProfileForTesting == null ? Profile.getLastUsedRegularProfile()
|
||||
: mProfileForTesting,
|
||||
ENDPOINT, METHOD, CONTENT_TYPE, getTabContextJson(tabContext), TIMEOUT_MS,
|
||||
new String[] {});
|
||||
new String[] {}, NetworkTrafficAnnotationTag.NO_TRAFFIC_ANNOTATION_YET);
|
||||
} catch (JSONException e) {
|
||||
// Soft failure for now so we don't crash the app and fall back on client side
|
||||
// providers.
|
||||
|
@ -3162,7 +3162,7 @@ public class TabListMediatorUnitTest {
|
||||
.when(mEndpointFetcherJniMock)
|
||||
.nativeFetchOAuth(any(Profile.class), anyString(), contains(entry.getKey()),
|
||||
anyString(), anyString(), any(String[].class), anyString(), anyLong(),
|
||||
any(Callback.class));
|
||||
anyInt(), any(Callback.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ package org.chromium.chrome.browser.tasks.tab_management.suggestions;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@ -115,21 +116,21 @@ public class TabSuggestionsServerFetcherUnitTest {
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) {
|
||||
Callback callback = (Callback) invocation.getArguments()[7];
|
||||
Callback callback = (Callback) invocation.getArguments()[8];
|
||||
callback.onResult(new EndpointResponse(response));
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(mEndpointFetcherJniMock)
|
||||
.nativeFetchChromeAPIKey(any(Profile.class), anyString(), anyString(), anyString(),
|
||||
anyString(), anyLong(), any(String[].class), any(Callback.class));
|
||||
anyString(), anyLong(), any(String[].class), anyInt(), any(Callback.class));
|
||||
}
|
||||
|
||||
private void verifyEndpointArguments() {
|
||||
verify(mEndpointFetcherJniMock)
|
||||
.nativeFetchChromeAPIKey(eq(mProfile), eq(EXPECTED_ENDPOINT_URL),
|
||||
eq(EXPECTED_METHOD), eq(EXPECTED_CONTENT_TYPE), any(String.class),
|
||||
eq(EXPECTED_TIMEOUT), any(String[].class), any(Callback.class));
|
||||
eq(EXPECTED_TIMEOUT), any(String[].class), anyInt(), any(Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -324,7 +324,7 @@ public abstract class ShoppingPersistedTabDataTestUtils {
|
||||
static void verifyEndpointFetcherCalled(EndpointFetcher.Natives endpointFetcher, int numTimes) {
|
||||
verify(endpointFetcher, times(numTimes))
|
||||
.nativeFetchChromeAPIKey(any(Profile.class), anyString(), anyString(), anyString(),
|
||||
anyString(), anyLong(), any(String[].class), any(Callback.class));
|
||||
anyString(), anyLong(), any(String[].class), anyInt(), any(Callback.class));
|
||||
}
|
||||
|
||||
static void verifyPriceTrackingOptimizationTypeCalled(
|
||||
@ -342,4 +342,4 @@ public abstract class ShoppingPersistedTabDataTestUtils {
|
||||
eq(HintsProto.OptimizationType.PRICE_TRACKING.getNumber()),
|
||||
any(OptimizationGuideCallback.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
package org.chromium.chrome.browser.tab.state;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@ -314,14 +315,14 @@ public class StorePersistedTabDataTest {
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) {
|
||||
Callback callback = (Callback) invocation.getArguments()[8];
|
||||
Callback callback = (Callback) invocation.getArguments()[9];
|
||||
callback.onResult(new EndpointResponse(response));
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(mEndpointFetcherJniMock)
|
||||
.nativeFetchOAuth(any(Profile.class), anyString(), anyString(), anyString(),
|
||||
anyString(), any(String[].class), anyString(), anyLong(),
|
||||
anyString(), any(String[].class), anyString(), anyLong(), anyInt(),
|
||||
any(Callback.class));
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.chromium.base.Callback;
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.net.NetworkTrafficAnnotationTag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -75,6 +76,8 @@ public final class CommerceSubscriptionsServiceProxy {
|
||||
*/
|
||||
public void get(@CommerceSubscription.CommerceSubscriptionType String type,
|
||||
Callback<List<CommerceSubscription>> callback) {
|
||||
// TODO(crbug.com/995852): Replace NO_TRAFFIC_ANNOTATION_YET with a real traffic
|
||||
// annotation.
|
||||
EndpointFetcher.fetchUsingOAuth(
|
||||
(response)
|
||||
-> {
|
||||
@ -84,10 +87,12 @@ public final class CommerceSubscriptionsServiceProxy {
|
||||
CommerceSubscriptionsServiceConfig.SUBSCRIPTIONS_SERVICE_BASE_URL.getValue()
|
||||
+ String.format(GET_SUBSCRIPTIONS_QUERY_PARAMS_TEMPLATE, type),
|
||||
GET_HTTPS_METHOD, CONTENT_TYPE, OAUTH_SCOPE, EMPTY_POST_DATA,
|
||||
HTTPS_REQUEST_TIMEOUT_MS);
|
||||
HTTPS_REQUEST_TIMEOUT_MS, NetworkTrafficAnnotationTag.NO_TRAFFIC_ANNOTATION_YET);
|
||||
}
|
||||
|
||||
private void manageSubscriptions(JSONObject requestPayload, Callback<Boolean> callback) {
|
||||
// TODO(crbug.com/995852): Replace NO_TRAFFIC_ANNOTATION_YET with a real traffic
|
||||
// annotation.
|
||||
EndpointFetcher.fetchUsingOAuth(
|
||||
(response)
|
||||
-> {
|
||||
@ -97,7 +102,7 @@ public final class CommerceSubscriptionsServiceProxy {
|
||||
mProfile, OAUTH_NAME,
|
||||
CommerceSubscriptionsServiceConfig.SUBSCRIPTIONS_SERVICE_BASE_URL.getValue(),
|
||||
POST_HTTPS_METHOD, CONTENT_TYPE, OAUTH_SCOPE, requestPayload.toString(),
|
||||
HTTPS_REQUEST_TIMEOUT_MS);
|
||||
HTTPS_REQUEST_TIMEOUT_MS, NetworkTrafficAnnotationTag.NO_TRAFFIC_ANNOTATION_YET);
|
||||
}
|
||||
|
||||
private boolean didManageSubscriptionCallSucceed(String responseString) {
|
||||
|
@ -6,6 +6,7 @@ package org.chromium.chrome.browser.subscriptions;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
@ -239,14 +240,14 @@ public class CommerceSubscriptionsServiceProxyUnitTest {
|
||||
verify(mEndpointFetcherJniMock, times(numTimes))
|
||||
.nativeFetchOAuth(any(Profile.class), any(String.class), eq(expectedUrl),
|
||||
eq(expectedMethod), eq(EXPECTED_CONTENT_TYPE), eq(EXPECTED_OAUTH_SCOPES),
|
||||
eq(expectedPayload), anyLong(), any(Callback.class));
|
||||
eq(expectedPayload), anyLong(), anyInt(), any(Callback.class));
|
||||
}
|
||||
|
||||
private void mockEndpointResponse(String response) {
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) {
|
||||
Callback callback = (Callback) invocation.getArguments()[8];
|
||||
Callback callback = (Callback) invocation.getArguments()[9];
|
||||
callback.onResult(new EndpointResponse(response));
|
||||
return null;
|
||||
}
|
||||
@ -254,6 +255,6 @@ public class CommerceSubscriptionsServiceProxyUnitTest {
|
||||
.when(mEndpointFetcherJniMock)
|
||||
.nativeFetchOAuth(any(Profile.class), any(String.class), any(String.class),
|
||||
any(String.class), eq(EXPECTED_CONTENT_TYPE), eq(EXPECTED_OAUTH_SCOPES),
|
||||
any(String.class), anyLong(), any(Callback.class));
|
||||
any(String.class), anyLong(), anyInt(), any(Callback.class));
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ android_library("java") {
|
||||
":jni_headers",
|
||||
"//base:base_java",
|
||||
"//chrome/browser/profiles/android:java",
|
||||
"//net/android:net_java",
|
||||
"//third_party/androidx:androidx_annotation_annotation_java",
|
||||
]
|
||||
sources = [
|
||||
|
@ -317,6 +317,7 @@ static void JNI_EndpointFetcher_NativeFetchOAuth(
|
||||
const base::android::JavaParamRef<jobjectArray>& jscopes,
|
||||
const base::android::JavaParamRef<jstring>& jpost_data,
|
||||
jlong jtimeout,
|
||||
jint jannotation_hash_code,
|
||||
const base::android::JavaParamRef<jobject>& jcallback) {
|
||||
std::vector<std::string> scopes;
|
||||
base::android::AppendJavaStringArrayToStringVector(env, jscopes, &scopes);
|
||||
@ -327,9 +328,8 @@ static void JNI_EndpointFetcher_NativeFetchOAuth(
|
||||
base::android::ConvertJavaStringToUTF8(env, jhttps_method),
|
||||
base::android::ConvertJavaStringToUTF8(env, jcontent_type), scopes,
|
||||
jtimeout, base::android::ConvertJavaStringToUTF8(env, jpost_data),
|
||||
// TODO(crbug.com/995852) Create a traffic annotation tag and configure it
|
||||
// as part of the EndpointFetcher call over JNI.
|
||||
NO_TRAFFIC_ANNOTATION_YET);
|
||||
net::NetworkTrafficAnnotationTag::FromJavaAnnotation(
|
||||
jannotation_hash_code));
|
||||
auto* const endpoint_fetcher_ptr = endpoint_fetcher.get();
|
||||
endpoint_fetcher_ptr->Fetch(
|
||||
base::BindOnce(&OnEndpointFetcherComplete,
|
||||
@ -348,6 +348,7 @@ static void JNI_EndpointFetcher_NativeFetchChromeAPIKey(
|
||||
const base::android::JavaParamRef<jstring>& jpost_data,
|
||||
jlong jtimeout,
|
||||
const base::android::JavaParamRef<jobjectArray>& jheaders,
|
||||
jint jannotation_hash_code,
|
||||
const base::android::JavaParamRef<jobject>& jcallback) {
|
||||
std::vector<std::string> headers;
|
||||
base::android::AppendJavaStringArrayToStringVector(env, jheaders, &headers);
|
||||
@ -357,7 +358,8 @@ static void JNI_EndpointFetcher_NativeFetchChromeAPIKey(
|
||||
base::android::ConvertJavaStringToUTF8(env, jhttps_method),
|
||||
base::android::ConvertJavaStringToUTF8(env, jcontent_type), jtimeout,
|
||||
base::android::ConvertJavaStringToUTF8(env, jpost_data), headers,
|
||||
NO_TRAFFIC_ANNOTATION_YET);
|
||||
net::NetworkTrafficAnnotationTag::FromJavaAnnotation(
|
||||
jannotation_hash_code));
|
||||
auto* const endpoint_fetcher_ptr = endpoint_fetcher.get();
|
||||
endpoint_fetcher_ptr->PerformRequest(
|
||||
base::BindOnce(&OnEndpointFetcherComplete,
|
||||
@ -372,11 +374,13 @@ static void JNI_EndpointFetcher_NativeFetchWithNoAuth(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& jprofile,
|
||||
const base::android::JavaParamRef<jstring>& jurl,
|
||||
jint jannotation_hash_code,
|
||||
const base::android::JavaParamRef<jobject>& jcallback) {
|
||||
auto endpoint_fetcher = std::make_unique<EndpointFetcher>(
|
||||
ProfileAndroid::FromProfileAndroid(jprofile),
|
||||
GURL(base::android::ConvertJavaStringToUTF8(env, jurl)),
|
||||
NO_TRAFFIC_ANNOTATION_YET);
|
||||
net::NetworkTrafficAnnotationTag::FromJavaAnnotation(
|
||||
jannotation_hash_code));
|
||||
auto* const endpoint_fetcher_ptr = endpoint_fetcher.get();
|
||||
endpoint_fetcher_ptr->PerformRequest(
|
||||
base::BindOnce(&OnEndpointFetcherComplete,
|
||||
|
@ -9,6 +9,7 @@ import androidx.annotation.MainThread;
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.base.annotations.NativeMethods;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.net.NetworkTrafficAnnotationTag;
|
||||
|
||||
/**
|
||||
* EndpointFetcher uses native EndpointFetcher to call a HTTPS endpoint and return
|
||||
@ -39,11 +40,12 @@ public final class EndpointFetcher {
|
||||
@MainThread
|
||||
public static void fetchUsingOAuth(Callback<EndpointResponse> callback, Profile profile,
|
||||
String oathConsumerName, String url, String httpsMethod, String contentType,
|
||||
String[] scopes, String postData, long timeout) {
|
||||
String[] scopes, String postData, long timeout,
|
||||
NetworkTrafficAnnotationTag annotation) {
|
||||
// EndpointFetcher currently does not support incognito mode
|
||||
assert !profile.isOffTheRecord();
|
||||
EndpointFetcherJni.get().nativeFetchOAuth(profile, oathConsumerName, url, httpsMethod,
|
||||
contentType, scopes, postData, timeout, callback);
|
||||
contentType, scopes, postData, timeout, annotation.getHashCode(), callback);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,22 +63,22 @@ public final class EndpointFetcher {
|
||||
@MainThread
|
||||
public static void fetchUsingChromeAPIKey(Callback<EndpointResponse> callback, Profile profile,
|
||||
String url, String httpsMethod, String contentType, String postData, long timeout,
|
||||
String[] headers) {
|
||||
String[] headers, NetworkTrafficAnnotationTag annotation) {
|
||||
// EndpointFetcher currently does not support incognito mode
|
||||
// assert !profile.isOffTheRecord();
|
||||
EndpointFetcherJni.get().nativeFetchChromeAPIKey(
|
||||
profile, url, httpsMethod, contentType, postData, timeout, headers, callback);
|
||||
EndpointFetcherJni.get().nativeFetchChromeAPIKey(profile, url, httpsMethod, contentType,
|
||||
postData, timeout, headers, annotation.getHashCode(), callback);
|
||||
}
|
||||
|
||||
@NativeMethods
|
||||
public interface Natives {
|
||||
void nativeFetchOAuth(Profile profile, String oathConsumerName, String url,
|
||||
String httpsMethod, String contentType, String[] scopes, String postData,
|
||||
long timeout, Callback<EndpointResponse> callback);
|
||||
long timeout, int annotationHashCode, Callback<EndpointResponse> callback);
|
||||
void nativeFetchChromeAPIKey(Profile profile, String url, String httpsMethod,
|
||||
String contentType, String postData, long timeout, String[] headers,
|
||||
int annotationHashCode, Callback<EndpointResponse> callback);
|
||||
void nativeFetchWithNoAuth(Profile profile, String url, int annotationHashCode,
|
||||
Callback<EndpointResponse> callback);
|
||||
void nativeFetchWithNoAuth(
|
||||
Profile profile, String url, Callback<EndpointResponse> callback);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ android_library("java") {
|
||||
"//chrome/browser/flags:java",
|
||||
"//chrome/browser/profiles/android:java",
|
||||
"//components/embedder_support/android:util_java",
|
||||
"//net/android:net_java",
|
||||
"//third_party/androidx:androidx_annotation_annotation_java",
|
||||
"//url:gurl_java",
|
||||
]
|
||||
|
@ -15,6 +15,7 @@ import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher;
|
||||
import org.chromium.chrome.browser.endpoint_fetcher.EndpointResponse;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.components.embedder_support.util.UrlUtilities;
|
||||
import org.chromium.net.NetworkTrafficAnnotationTag;
|
||||
import org.chromium.url.GURL;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -57,6 +58,8 @@ public class PageAnnotationsServiceProxy {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(crbug.com/995852): Replace NO_TRAFFIC_ANNOTATION_YET with a real traffic
|
||||
// annotation.
|
||||
EndpointFetcher.fetchUsingChromeAPIKey(
|
||||
(endpointResponse)
|
||||
-> { fetchCallback(endpointResponse, callback); },
|
||||
@ -65,7 +68,8 @@ public class PageAnnotationsServiceProxy {
|
||||
+ GET_ANNOTATIONS_QUERY_PARAMS_TEMPLATE,
|
||||
UrlUtilities.escapeQueryParamValue(url.getSpec(), false)),
|
||||
HTTPS_METHOD, CONTENT_TYPE, EMPTY_POST_DATA, TIMEOUT_MS,
|
||||
new String[] {ACCEPT_LANGUAGE_KEY, LocaleUtils.getDefaultLocaleListString()});
|
||||
new String[] {ACCEPT_LANGUAGE_KEY, LocaleUtils.getDefaultLocaleListString()},
|
||||
NetworkTrafficAnnotationTag.NO_TRAFFIC_ANNOTATION_YET);
|
||||
}
|
||||
|
||||
private void fetchCallback(EndpointResponse response,
|
||||
@ -90,4 +94,4 @@ public class PageAnnotationsServiceProxy {
|
||||
|
||||
resultCallback.onResult(new SinglePageAnnotationsServiceResponse(annotations));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ android_library("javatests") {
|
||||
"//chrome/browser/page_annotations/android:java",
|
||||
"//chrome/browser/profiles/android:java",
|
||||
"//chrome/test/android:chrome_java_test_support",
|
||||
"//net/android:net_java",
|
||||
"//third_party/androidx:androidx_test_core_java",
|
||||
"//third_party/androidx:androidx_test_runner_java",
|
||||
"//third_party/junit",
|
||||
|
@ -5,6 +5,7 @@
|
||||
package org.chromium.chrome.browser.page_annotations;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@ -168,21 +169,21 @@ public class PageAnnotationsServiceProxyUnitTest {
|
||||
verify(mEndpointFetcherJniMock, times(numTimes))
|
||||
.nativeFetchChromeAPIKey(any(Profile.class), eq(expectedUrl), eq(EXPECTED_METHOD),
|
||||
eq(EXPECTED_CONTENT_TYPE), anyString(), anyLong(), eq(expectedHeaders),
|
||||
any(Callback.class));
|
||||
anyInt(), any(Callback.class));
|
||||
}
|
||||
|
||||
private void mockEndpointResponse(String response) {
|
||||
doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) {
|
||||
Callback callback = (Callback) invocation.getArguments()[7];
|
||||
Callback callback = (Callback) invocation.getArguments()[8];
|
||||
callback.onResult(new EndpointResponse(response));
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.when(mEndpointFetcherJniMock)
|
||||
.nativeFetchChromeAPIKey(any(Profile.class), anyString(), anyString(), anyString(),
|
||||
anyString(), anyLong(), any(String[].class), any(Callback.class));
|
||||
anyString(), anyLong(), any(String[].class), anyInt(), any(Callback.class));
|
||||
}
|
||||
|
||||
private void verifyAnnotations(List<PageAnnotation> annotations) {
|
||||
|
@ -2,4 +2,5 @@ include_rules = [
|
||||
"+chrome/browser/tabpersistence",
|
||||
"+chrome/browser/page_annotations",
|
||||
"+components/payments/content/android",
|
||||
]
|
||||
"+net/android",
|
||||
]
|
||||
|
@ -19,6 +19,7 @@ import org.chromium.chrome.browser.endpoint_fetcher.EndpointFetcher;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.chrome.browser.tab.proto.StorePersistedTabData.StorePersistedTabDataProto;
|
||||
import org.chromium.net.NetworkTrafficAnnotationTag;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Locale;
|
||||
@ -277,6 +278,8 @@ public class StorePersistedTabData extends PersistedTabData {
|
||||
* @param callback {@link Callback} {@link StorePersistedTabData is passed back in}
|
||||
*/
|
||||
public static void from(Tab tab, Callback<StorePersistedTabData> callback) {
|
||||
// TODO(crbug.com/995852): Replace NO_TRAFFIC_ANNOTATION_YET with a real traffic
|
||||
// annotation.
|
||||
PersistedTabData.from(tab,
|
||||
(data, storage, id)
|
||||
-> { return new StorePersistedTabData(tab, data, storage, id); },
|
||||
@ -290,7 +293,8 @@ public class StorePersistedTabData extends PersistedTabData {
|
||||
},
|
||||
Profile.getLastUsedRegularProfile(), PERSISTED_TAB_DATA_ID,
|
||||
String.format(Locale.US, ENDPOINT, tab.getUrl().getSpec()),
|
||||
HTTPS_METHOD, CONTENT_TYPE, SCOPES, EMPTY_POST_DATA, TIMEOUT_MS);
|
||||
HTTPS_METHOD, CONTENT_TYPE, SCOPES, EMPTY_POST_DATA, TIMEOUT_MS,
|
||||
NetworkTrafficAnnotationTag.NO_TRAFFIC_ANNOTATION_YET);
|
||||
},
|
||||
StorePersistedTabData.class, callback);
|
||||
}
|
||||
@ -373,4 +377,4 @@ public class StorePersistedTabData extends PersistedTabData {
|
||||
|
||||
return Integer.parseInt(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ android_library("net_java") {
|
||||
"java/src/org/chromium/net/NetworkActivationRequest.java",
|
||||
"java/src/org/chromium/net/NetworkChangeNotifier.java",
|
||||
"java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java",
|
||||
"java/src/org/chromium/net/NetworkTrafficAnnotationTag.java",
|
||||
"java/src/org/chromium/net/ProxyBroadcastReceiver.java",
|
||||
"java/src/org/chromium/net/ProxyChangeListener.java",
|
||||
"java/src/org/chromium/net/RegistrationPolicyAlwaysRegister.java",
|
||||
@ -221,7 +222,10 @@ java_cpp_enum("net_android_java_enums_srcjar") {
|
||||
}
|
||||
|
||||
junit_binary("net_junit_tests") {
|
||||
sources = [ "junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java" ]
|
||||
sources = [
|
||||
"junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java",
|
||||
"junit/src/org/chromium/net/NetworkTrafficAnnotationTagTest.java",
|
||||
]
|
||||
deps = [
|
||||
":net_java",
|
||||
"//base:base_java",
|
||||
|
@ -0,0 +1,109 @@
|
||||
// Copyright 2021 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.net;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Network Traffic Annotations document the purpose of a particular network request, and its impact
|
||||
* on privacy.
|
||||
*
|
||||
* This documentation is typically meant for system administrators in an enterprise setting. It
|
||||
* should be easy for them to read and understand, and answer the following questions:
|
||||
*
|
||||
* 1. When and why does Chrome make this network request?
|
||||
* 2. Does this network request send any sensitive data?
|
||||
* 3. Where does the request go? (e.g. a Google server, a website the user is viewing...)
|
||||
* 4. How can I disable it if I don't like it?
|
||||
*/
|
||||
public class NetworkTrafficAnnotationTag {
|
||||
/**
|
||||
* For network requests that aren't documented yet. These should be
|
||||
* accompanied with a TODO with a bug/owner to write their documentation.
|
||||
*/
|
||||
public static final NetworkTrafficAnnotationTag NO_TRAFFIC_ANNOTATION_YET =
|
||||
createComplete("undefined", "Nothing here yet.");
|
||||
|
||||
/**
|
||||
* For network requests that don't need an annotation, because they're in an
|
||||
* allowlisted file (see tools/traffic_annotation/auditor/safe_list.txt).
|
||||
*/
|
||||
public static final NetworkTrafficAnnotationTag MISSING_TRAFFIC_ANNOTATION =
|
||||
createComplete("undefined", "Function called without traffic annotation.");
|
||||
|
||||
/** For network requests made in tests, don't bother writing documentation. */
|
||||
public static final NetworkTrafficAnnotationTag TRAFFIC_ANNOTATION_FOR_TESTS =
|
||||
createComplete("test", "Traffic annotation for unit, browser and other tests");
|
||||
/**
|
||||
* Create a self-contained tag describing a network request made by Chromium. This is the most
|
||||
* common factory method.
|
||||
*
|
||||
* The C++ equivalent is DefineNetworkTrafficAnnotation().
|
||||
*
|
||||
* @param uniqueId a String that uniquely identifies this annotations across all of Chromium
|
||||
* source code.
|
||||
* @param proto a text-encoded NetworkTrafficAnnotation protobuf (see
|
||||
* chrome/browser/privacy/traffic_annotation.proto).
|
||||
*/
|
||||
public static NetworkTrafficAnnotationTag createComplete(String uniqueId, String proto) {
|
||||
return new NetworkTrafficAnnotationTag(uniqueId);
|
||||
}
|
||||
|
||||
// TODO(crbug.com/1231780): Add Partial, Completing, Branched-Completing, and
|
||||
// Mutable(?) factory methods.
|
||||
|
||||
/**
|
||||
* At runtime, an annotation tag is just a hashCode. Most of the validation is done on CQ, so
|
||||
* there's no point keeping track of everything at runtime.
|
||||
*
|
||||
* This field is referenced from C++, so don't change it without updating
|
||||
* net/traffic_annotation/network_traffic_annotation.h.
|
||||
*/
|
||||
// TODO(crbug.com/1231780): Unlike the C++ version though, the string will still get compiled
|
||||
// into the APK, and get loaded into memory when the constructor is called... Is there a way to
|
||||
// tell Java, "No, I don't actually need this string at runtime"? We should investigate.
|
||||
private final int mHashCode;
|
||||
|
||||
/**
|
||||
* @return the hash code of uniqueId, which uniquely identifies this annotation.
|
||||
*/
|
||||
public int getHashCode() {
|
||||
return mHashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for NetworkTrafficAnnotationTag. Consumers of this API should use
|
||||
* CreateComplete() instead.
|
||||
*
|
||||
* @param uniqueId a String that uniquely identifies this annotation across all of Chromium
|
||||
* source code.
|
||||
*/
|
||||
private NetworkTrafficAnnotationTag(String uniqueId) {
|
||||
mHashCode = iterativeHash(uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hashcode of a string, as per the recursive_hash() function used in C++ code.
|
||||
*
|
||||
* This is NOT the same as Java's built-in hashCode() function, because we really want to
|
||||
* produce the same hashcode that auditor.py produces.
|
||||
*
|
||||
* @param s the String to calculate the hash on.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static int iterativeHash(String s) {
|
||||
// Multiplying by 31 would cause an overflow if using `int', so use `long' instead.
|
||||
long acc = 0;
|
||||
// Encode the string as UTF-8.
|
||||
byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
|
||||
for (byte b : bytes) {
|
||||
acc = (acc * 31 + b) % 138003713;
|
||||
}
|
||||
// The final result always fits in an `int' thanks to the modulo.
|
||||
return (int) acc;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// Copyright 2021 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.net;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.chromium.base.test.BaseRobolectricTestRunner;
|
||||
|
||||
/**
|
||||
* Tests calculating the hash for Network Traffic Annotations.
|
||||
*/
|
||||
@RunWith(BaseRobolectricTestRunner.class)
|
||||
public class NetworkTrafficAnnotationTagTest {
|
||||
@Test
|
||||
public void testIterativeHash() throws Exception {
|
||||
// Reference values obtained from
|
||||
// tools/traffic_annotation/scripts/auditor/auditor_tests.py.
|
||||
assertEquals(3556498, NetworkTrafficAnnotationTag.iterativeHash("test"));
|
||||
assertEquals(10236504, NetworkTrafficAnnotationTag.iterativeHash("unique_id"));
|
||||
assertEquals(70581310, NetworkTrafficAnnotationTag.iterativeHash("123_id"));
|
||||
assertEquals(69491511, NetworkTrafficAnnotationTag.iterativeHash("ID123"));
|
||||
assertEquals(98652091,
|
||||
NetworkTrafficAnnotationTag.iterativeHash("a_unique_"
|
||||
+ "looooooooooooooooooooooooooooooooooooooooooooooooooooooong_id"));
|
||||
assertEquals(124751853, NetworkTrafficAnnotationTag.iterativeHash("bébé"));
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ source_set("traffic_annotation") {
|
||||
"//base",
|
||||
"//build:chromeos_buildflags",
|
||||
]
|
||||
if (is_android) {
|
||||
sources += [ "network_traffic_annotation_android.cc" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("test_support") {
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include "build/build_config.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
#include "base/android/scoped_java_ref.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// Recursively compute hash code of the given string as a constant expression.
|
||||
@ -73,6 +77,13 @@ struct NetworkTrafficAnnotationTag {
|
||||
const PartialNetworkTrafficAnnotationTag& partial_annotation,
|
||||
const char (&proto)[N3]);
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
// Allows C++ methods to receive a Java NetworkTrafficAnnotationTag via JNI,
|
||||
// and convert it to the C++ version.
|
||||
static NetworkTrafficAnnotationTag FromJavaAnnotation(
|
||||
int32_t unique_id_hash_code);
|
||||
#endif
|
||||
|
||||
friend struct MutableNetworkTrafficAnnotationTag;
|
||||
|
||||
private:
|
||||
|
15
net/traffic_annotation/network_traffic_annotation_android.cc
Normal file
15
net/traffic_annotation/network_traffic_annotation_android.cc
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2021 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "net/traffic_annotation/network_traffic_annotation.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
// static
|
||||
NetworkTrafficAnnotationTag NetworkTrafficAnnotationTag::FromJavaAnnotation(
|
||||
int32_t unique_id_hash_code) {
|
||||
return NetworkTrafficAnnotationTag(unique_id_hash_code);
|
||||
}
|
||||
|
||||
} // namespace net
|
@ -9,6 +9,7 @@ missing,net/url_request/url_fetcher.cc
|
||||
missing,net/url_request/url_request_context.cc
|
||||
mutable_tag,components/download/internal/background_service/proto_conversions.cc
|
||||
mutable_tag,chrome/browser/media/router/providers/openscreen/platform/udp_socket.cc
|
||||
mutable_tag,net/traffic_annotation/network_traffic_annotation.h
|
||||
test_annotation,components/safe_search_api/stub_url_checker.cc
|
||||
test_annotation,net/quic/quic_chromium_client_session_peer.cc
|
||||
test_annotation,net/tools/quic/quic_http_proxy_backend_stream.cc
|
||||
|
Reference in New Issue
Block a user