Published Devices Client tool release: 1.1.0
This commit is contained in:
369
tools/published_devices_client/WORKSPACE
Normal file
369
tools/published_devices_client/WORKSPACE
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
# JTS Framework WORKSPACE.
|
||||||
|
|
||||||
|
workspace(name = "jts")
|
||||||
|
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository", "git_repository")
|
||||||
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
|
|
||||||
|
# In Bazel 2.0, Maven rules provided via new rules_jvm_external.
|
||||||
|
RULES_JVM_EXTERNAL_TAG = "3.1"
|
||||||
|
RULES_JVM_EXTERNAL_SHA = "e246373de2353f3d34d35814947aa8b7d0dd1a58c2f7a6c41cfeaff3007c2d14"
|
||||||
|
http_archive(
|
||||||
|
name = "rules_jvm_external",
|
||||||
|
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
|
||||||
|
sha256 = RULES_JVM_EXTERNAL_SHA,
|
||||||
|
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
|
||||||
|
)
|
||||||
|
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||||
|
|
||||||
|
# Google Guice.
|
||||||
|
maven_install(
|
||||||
|
name = "google_guice",
|
||||||
|
artifacts = ["com.google.inject:guice:4.2.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Appache core framework.
|
||||||
|
maven_install(
|
||||||
|
name = "apache_httpcore",
|
||||||
|
artifacts = ["org.apache.httpcomponents:httpcore:4.4.10"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Google APIs client library
|
||||||
|
maven_install(
|
||||||
|
name = "google_api",
|
||||||
|
artifacts = ["com.google.api-client:google-api-client:1.30.2"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Google HTTP Client
|
||||||
|
maven_install(
|
||||||
|
name = "google_http_client",
|
||||||
|
artifacts = ["com.google.http-client:google-http-client:1.30.2"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Google HTTP Client Jackson2 Extensions
|
||||||
|
maven_install(
|
||||||
|
name = "jackson2",
|
||||||
|
artifacts = ["com.google.http-client:google-http-client-jackson2:1.31.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
maven_install(
|
||||||
|
name = "jackson_core",
|
||||||
|
artifacts = ["com.fasterxml.jackson.core:jackson-core:2.10.0.pr2"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Google Oauth2 API
|
||||||
|
maven_install(
|
||||||
|
name = "google_oauth2",
|
||||||
|
artifacts = ["com.google.oauth-client:google-oauth-client:1.30.1"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Google Java common framework.
|
||||||
|
maven_install(
|
||||||
|
name = "google_guava",
|
||||||
|
artifacts = ["com.google.guava:guava:25.1-jre"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# GRPC
|
||||||
|
git_repository(
|
||||||
|
name = "io_grpc_grpc_java",
|
||||||
|
remote = "https://github.com/grpc/grpc-java.git",
|
||||||
|
tag = "v1.23.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
# GRPC Core
|
||||||
|
maven_install(
|
||||||
|
name = "grpc_core",
|
||||||
|
artifacts = ["io.grpc:grpc-core:1.23.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# GRPC Netty
|
||||||
|
maven_install(
|
||||||
|
name = "grpc_netty",
|
||||||
|
artifacts = ["io.grpc:grpc-netty:1.23.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
maven_install(
|
||||||
|
name = "grpc_netty_all",
|
||||||
|
artifacts = ["io.netty:netty-all:4.1.41.Final"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# GRPC Stub
|
||||||
|
maven_install(
|
||||||
|
name = "grpc_stub",
|
||||||
|
artifacts = ["io.grpc:grpc-stub:1.23.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# GRPC Contenxt
|
||||||
|
maven_install(
|
||||||
|
name = "grpc_context",
|
||||||
|
artifacts = ["io.grpc:grpc-context:1.18.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# GSON
|
||||||
|
maven_install(
|
||||||
|
name = "gson",
|
||||||
|
artifacts = ["com.google.code.gson:gson:2.8.6"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Netty TcNative (for GRPC)
|
||||||
|
maven_install(
|
||||||
|
name = "netty_tcnative",
|
||||||
|
artifacts = ["io.netty:netty-tcnative:2.0.25.Final"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Netty BoringSSL
|
||||||
|
maven_install(
|
||||||
|
name = "netty_boringssl",
|
||||||
|
artifacts = ["io.netty:netty-tcnative-boringssl-static:2.0.25.Final"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Open Census (for GRPC)
|
||||||
|
maven_install(
|
||||||
|
name = "open_census_api",
|
||||||
|
artifacts = ["io.opencensus:opencensus-api:0.24.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
maven_install(
|
||||||
|
name = "open_census",
|
||||||
|
artifacts = ["io.opencensus:opencensus-contrib-http-jetty-client:0.19.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
maven_install(
|
||||||
|
name = "open_census_util",
|
||||||
|
artifacts = ["io.opencensus:opencensus-contrib-http-util:0.19.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
maven_install(
|
||||||
|
name = "open_census_grpc_metrics",
|
||||||
|
artifacts = ["io.opencensus:opencensus-contrib-grpc-metrics:0.24.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Perfmark (GRPC)
|
||||||
|
maven_install(
|
||||||
|
name = "io_perfmark_api",
|
||||||
|
artifacts = ["io.perfmark:perfmark-api:0.17.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Google Protobuf Protos
|
||||||
|
PROTOBUF_BUILD_FILE = """
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
PROTO_FILES = [
|
||||||
|
"google/protobuf/descriptor.proto",
|
||||||
|
]
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "protobuf_files",
|
||||||
|
srcs = PROTO_FILES,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "protobuf_protos",
|
||||||
|
srcs = [":protobuf_files"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
|
git_repository(
|
||||||
|
name = "com_github_googleapis_googleapis",
|
||||||
|
remote = "https://github.com/googleapis/googleapis.git",
|
||||||
|
branch = "master",
|
||||||
|
)
|
||||||
|
load("@com_github_googleapis_googleapis//:repository_rules.bzl", "switched_rules_by_language")
|
||||||
|
switched_rules_by_language(
|
||||||
|
name = "com_google_googleapis_imports",
|
||||||
|
java = True)
|
||||||
|
|
||||||
|
http_archive(
|
||||||
|
name = "common_protos",
|
||||||
|
build_file_content = PROTOBUF_BUILD_FILE,
|
||||||
|
strip_prefix = "protobuf-3.9.1/src",
|
||||||
|
urls = [
|
||||||
|
"https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protobuf-all-3.9.1.tar.gz",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Java commandline framework.
|
||||||
|
maven_install(
|
||||||
|
name = "jcommander",
|
||||||
|
artifacts = ["com.beust:jcommander:1.72"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
#Javax Inject (for Guice).
|
||||||
|
maven_install(
|
||||||
|
name = "javax_inject",
|
||||||
|
artifacts = ["javax.inject:javax.inject:1"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# JSON Java.
|
||||||
|
maven_install(
|
||||||
|
name = "json",
|
||||||
|
artifacts = ["org.json:json:20090211"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# JSR305 Annotations.
|
||||||
|
maven_install(
|
||||||
|
name = "jsr305_annotations",
|
||||||
|
artifacts = ["com.google.code.findbugs:jsr305:3.0.2"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# AOP (for Guice).
|
||||||
|
maven_install(
|
||||||
|
name = "aopalliance",
|
||||||
|
artifacts = ["aopalliance:aopalliance:1.0"],
|
||||||
|
repositories = [
|
||||||
|
"https://jcenter.bintray.com",
|
||||||
|
"https://maven.google.com",
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Protocol Buffer compiler.
|
||||||
|
git_repository(
|
||||||
|
name = "com_google_protobuf",
|
||||||
|
remote = "https://github.com/google/protobuf.git",
|
||||||
|
tag = "v3.9.1",
|
||||||
|
)
|
||||||
|
|
||||||
|
bind(
|
||||||
|
name = "protobuf",
|
||||||
|
actual = "@com_google_protobuf//:protobuf",
|
||||||
|
)
|
||||||
|
|
||||||
|
bind(
|
||||||
|
name = "protobuf_java",
|
||||||
|
actual = "@com_google_protobuf//:protobuf_java",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Loads necessary bazel rules for later consumption.
|
||||||
|
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
|
||||||
|
grpc_java_repositories()
|
||||||
|
|
||||||
|
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||||
|
protobuf_deps()
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
|
||||||
|
# Published Devices protocol buffer definitions for the
|
||||||
|
# Widevine Published Devices One Platform API service.
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "published_devices_proto",
|
||||||
|
srcs = ["published_devices.proto"],
|
||||||
|
deps = [
|
||||||
|
":device_security_profiles_proto",
|
||||||
|
"@com_github_googleapis_googleapis//google/api:annotations_proto",
|
||||||
|
"@com_github_googleapis_googleapis//google/api:field_behavior_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "device_security_profiles_proto",
|
||||||
|
srcs = ["device_security_profiles.proto"],
|
||||||
|
deps = [
|
||||||
|
"@com_github_googleapis_googleapis//google/api:field_behavior_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_proto_library(
|
||||||
|
name = "published_devices_java_proto",
|
||||||
|
deps = [":published_devices_proto"],
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
java_grpc_library(
|
||||||
|
name = "published_devices_grpc",
|
||||||
|
srcs = [":published_devices_proto"],
|
||||||
|
deps = [
|
||||||
|
":published_devices_java_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
// This file contains the proto definitions of DeviceSecurityProfile needed for
|
||||||
|
// the PublishedDevicesService.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package google.chrome.widevine.contentpartners.v1beta1;
|
||||||
|
|
||||||
|
import "google/api/field_behavior.proto";
|
||||||
|
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_outer_classname = "DeviceSecurityProfilesProto";
|
||||||
|
option java_package = "com.google.chrome.widevine.contentpartners.v1beta1";
|
||||||
|
|
||||||
|
// The DeviceSecurityProfileCriteria is produced by the client (a Widevine
|
||||||
|
// SDK). It is serialized and embedded in the
|
||||||
|
// ListDeviceSecurityProfilesRequest.
|
||||||
|
message DeviceSecurityProfileCriteria {
|
||||||
|
// Content provider who wants to get the DSPs. Required.
|
||||||
|
string content_provider = 1 [(google.api.field_behavior) = REQUIRED];
|
||||||
|
// Content owners who own the DSPs. If this field is empty, return all
|
||||||
|
// DSPs that the content provider is included. Otherwise, a list of DSPs
|
||||||
|
// owned by the listed content_owners would be filtered for the requested
|
||||||
|
// provider. Optional field.
|
||||||
|
repeated string content_owners = 2 [(google.api.field_behavior) = OPTIONAL];
|
||||||
|
}
|
||||||
|
|
||||||
|
// A request sent to Widevine Published Server to retrieve
|
||||||
|
// the DeviceSecurityProfiles.
|
||||||
|
// (-- api-linter: core::0132::request-unknown-fields=disabled
|
||||||
|
// api-linter: core::0132::request-parent-required=disabled
|
||||||
|
// api-linter: core::0158::request-page-token-field=disabled
|
||||||
|
// api-linter: core::0158::request-page-size-field=disabled
|
||||||
|
// aip.dev/not-precedent: This is a non-standard, non-precedent API that
|
||||||
|
// cannot use pagination. It has no parent, page_size and page_token.
|
||||||
|
// Pagination is not appropriate. --)
|
||||||
|
message ListDeviceSecurityProfilesRequest {
|
||||||
|
// DeviceSecurityProfileCriteria for List request. Required.
|
||||||
|
DeviceSecurityProfileCriteria device_security_profile_criteria = 1
|
||||||
|
[(google.api.field_behavior) = REQUIRED];
|
||||||
|
}
|
||||||
|
|
||||||
|
// A signed message which contains a serialized DeviceSecurityProfileList and
|
||||||
|
// the signature.
|
||||||
|
// (--GOOGLE_INTERNAL
|
||||||
|
// This message is copied from
|
||||||
|
// video/widevine/protos/public/device_security_profile_list.proto
|
||||||
|
// --)
|
||||||
|
message SignedDeviceSecurityProfiles {
|
||||||
|
// Serialized DeviceSecurityProfileList. Required.
|
||||||
|
// A device security profile list contains device security profiles
|
||||||
|
// defined by the content owner. Each DSP aggregates the device's
|
||||||
|
// capabilities, such as security profile level, minimum output requirements,
|
||||||
|
// minimum security requirements for this profile. The information is intended
|
||||||
|
// to be shared publicly.
|
||||||
|
bytes device_security_profiles = 1 [(google.api.field_behavior) = REQUIRED];
|
||||||
|
// Signature of device_security_profiles. Signed with root
|
||||||
|
// certificate private key using RSASSA-PSS. Required.
|
||||||
|
bytes signature = 2 [(google.api.field_behavior) = REQUIRED];
|
||||||
|
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||||
|
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||||
|
}
|
||||||
|
|
||||||
|
// A response returned from Widevine Published Server which contains a signed
|
||||||
|
// DeviceSecurityProfileList message.
|
||||||
|
// (-- api-linter: core::0132::response-unknown-fields=disabled
|
||||||
|
// api-linter: core::0158::response-repeated-first-field=disabled
|
||||||
|
// api-linter: core::0158::response-next-page-token-field=disabled
|
||||||
|
// aip.dev/not-precedent: This is a non-standard, non-precedent API that
|
||||||
|
// cannot use pagination. We serialize and sign the list data in a signed
|
||||||
|
// message, which is used in the response. The first field is not repeated
|
||||||
|
// and response has no next_page_token field. The
|
||||||
|
// SignedDeviceSecurityProfiles is intended to be consumed as a single blob.
|
||||||
|
// Pagination is not appropriate. --)
|
||||||
|
message ListDeviceSecurityProfilesResponse {
|
||||||
|
// A signed message which contains a serialized DeviceSecurityProfileList and
|
||||||
|
// the signature.
|
||||||
|
SignedDeviceSecurityProfiles signed_device_security_profiles = 1
|
||||||
|
[(google.api.field_behavior) = REQUIRED];
|
||||||
|
}
|
||||||
|
|
||||||
|
// A representation of a hash algorithm used in signature.
|
||||||
|
// (--GOOGLE_INTERNAL
|
||||||
|
// This enum is copied from
|
||||||
|
// video/widevine/protos/public/hash_algorithm.proto
|
||||||
|
// --)
|
||||||
|
enum HashAlgorithm {
|
||||||
|
// Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms
|
||||||
|
// and SHA_1 shall be used otherwise.
|
||||||
|
HASH_ALGORITHM_UNSPECIFIED = 0;
|
||||||
|
// Secure Hash Algorithm 1 (SHA-1).
|
||||||
|
HASH_ALGORITHM_SHA_1 = 1;
|
||||||
|
// Secure Hash Algorithm 2 256 bits (SHA-256).
|
||||||
|
HASH_ALGORITHM_SHA_256 = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
// This file contains the definitions needed for the PublishedDevicesService.
|
||||||
|
// The PublishedDevicesService allows clients to retrieve a signed and
|
||||||
|
// verifiable list of devices and device security profiles that support the
|
||||||
|
// Widevine Digital Rights Management (DRM) solution.
|
||||||
|
//
|
||||||
|
// (--GOOGLE_INTERNAL
|
||||||
|
// This proto is intended to support a feature of the "Widevine API" where
|
||||||
|
// external content providers will retrieve device certificate status list
|
||||||
|
// as well as device secruity profiles to achieve better and more secure
|
||||||
|
// playback experience.
|
||||||
|
//
|
||||||
|
// For more info about the service, please see design doc
|
||||||
|
// https://docs.google.com/document/d/1ZClc0HJuFlijDrdZxcR_DmNOi6Hqo7bjjEtewLnafas/edit?usp=sharing
|
||||||
|
// --)
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package google.chrome.widevine.contentpartners.v1beta1;
|
||||||
|
|
||||||
|
import "google/api/annotations.proto";
|
||||||
|
import "google/api/field_behavior.proto";
|
||||||
|
import "google/chrome/widevine/contentpartners/v1beta1/device_security_profiles.proto";
|
||||||
|
|
||||||
|
option csharp_namespace = "Google.Chrome.Widevine.ContentPartners.V1Beta1";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_outer_classname = "PublishedDevicesProtos";
|
||||||
|
option java_package = "com.google.chrome.widevine.contentpartners.v1beta1";
|
||||||
|
|
||||||
|
// GCWPD is an acronym for Google Chrome Widevine Published Devices.
|
||||||
|
option objc_class_prefix = "GCWPD";
|
||||||
|
|
||||||
|
|
||||||
|
// This service produces a list of Widevine supported devices
|
||||||
|
// signed by a certificate that can be verified by the client.
|
||||||
|
service PublishedDevicesService {
|
||||||
|
// Return the PublishedDevices containing the list of devices and a signature.
|
||||||
|
// The request is used to authenticate the client.
|
||||||
|
rpc GetPublishedDevices(PublishedDevicesRequest) returns (PublishedDevices) {
|
||||||
|
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/v1beta1/publishedDevices:getSignedBatch"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the ListDeviceSecurityProfilesResponse containing a list of
|
||||||
|
// device security profiles.
|
||||||
|
rpc ListDeviceSecurityProfiles(ListDeviceSecurityProfilesRequest)
|
||||||
|
returns (ListDeviceSecurityProfilesResponse) {
|
||||||
|
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/v1beta1/deviceSecurityProfiles:listDeviceSecurityProfiles"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The SdkClientInformation is produced by the client (a Widevine SDK). It is
|
||||||
|
// serialized and embedded in the PublishedDevicesRequest. It is used to
|
||||||
|
// declare attributes of the client's SDK including the Widevine-issued service
|
||||||
|
// certificate that is used by the client.
|
||||||
|
message SdkClientInformation {
|
||||||
|
// The version of sdk. Required.
|
||||||
|
string sdk_version = 1;
|
||||||
|
// POSIX time, in seconds, when this request was created. Required.
|
||||||
|
uint64 sdk_time_seconds = 2;
|
||||||
|
// The serialized service certificate used to sign the request. Required.
|
||||||
|
bytes service_certificate = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A signed request sent to Widevine Provisioning Server (keysmith) to retrieve
|
||||||
|
// the PublishedDevices.
|
||||||
|
message PublishedDevicesRequest {
|
||||||
|
// A serialized SdkClientInformation proto. Required.
|
||||||
|
bytes sdk_client_information = 1;
|
||||||
|
|
||||||
|
// This is the SHA256 digest, PKCS#7 padded signature of the
|
||||||
|
// sdk_client_information field. This signature uses the
|
||||||
|
// RSA private key corresponding to the server certificate. Required.
|
||||||
|
bytes signature = 2;
|
||||||
|
|
||||||
|
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||||
|
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains a serialized DeviceCertificateStatusList and the signature.
|
||||||
|
message PublishedDevices {
|
||||||
|
// Serialized DeviceCertificateStatusList. Required.
|
||||||
|
// A device certificate status list contains information about various
|
||||||
|
// device series information such as the make, model and status (RELEASED,
|
||||||
|
// IN_TESTING, REVOKED, etc).The information is intended to be shared
|
||||||
|
// publicly.
|
||||||
|
bytes published_devices = 1;
|
||||||
|
|
||||||
|
// Signature of device_certificate_status_list_request. Signed with root
|
||||||
|
// certificate private key using RSASSA-PSS. Required.
|
||||||
|
bytes signature = 2;
|
||||||
|
|
||||||
|
// Optional field that indicates the hash algorithm used in signature scheme.
|
||||||
|
HashAlgorithm hash_algorithm = 3 [(google.api.field_behavior) = OPTIONAL];
|
||||||
|
}
|
||||||
21
tools/published_devices_client/httpclient/BUILD
Normal file
21
tools/published_devices_client/httpclient/BUILD
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
# Desciption:
|
||||||
|
# JTS http clients.
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_library(
|
||||||
|
name = "httpclient",
|
||||||
|
srcs = glob(["*.java"]),
|
||||||
|
deps = [
|
||||||
|
"@google_guice//:com_google_inject_guice",
|
||||||
|
"@json//:org_json_json",
|
||||||
|
"@google_api//:com_google_api_client_google_api_client",
|
||||||
|
"@google_http_client//:com_google_http_client_google_http_client",
|
||||||
|
"@google_oauth2//:com_google_oauth_client_google_oauth_client",
|
||||||
|
"@jackson2//:com_google_http_client_google_http_client_jackson2",
|
||||||
|
"@jackson_core//:com_fasterxml_jackson_core_jackson_core",
|
||||||
|
],
|
||||||
|
)
|
||||||
56
tools/published_devices_client/httpclient/Credentials.java
Normal file
56
tools/published_devices_client/httpclient/Credentials.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
package com.google.video.widevine.jts.httpclient;
|
||||||
|
|
||||||
|
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JTS Cloud Credentials.
|
||||||
|
*
|
||||||
|
* Provides Oauth2 authentication, and access/refresh tokens.
|
||||||
|
*/
|
||||||
|
public class Credentials {
|
||||||
|
|
||||||
|
private static final List<String> SCOPES = Arrays.asList(
|
||||||
|
"https://www.googleapis.com/auth/cloud-platform",
|
||||||
|
"https://www.googleapis.com/auth/widevine/frontend");
|
||||||
|
private static final int MIN_ACCESS_TOKEN_REFRESH_SEC = 1200;
|
||||||
|
private static final Logger logger = Logger.getLogger(Credentials.class.getName());
|
||||||
|
|
||||||
|
private String credentialsJsonFile = null;
|
||||||
|
private GoogleCredential googleCredential = null;
|
||||||
|
private String accessToken = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credentials Constructor.
|
||||||
|
*
|
||||||
|
* @param credentialsJsonFile The full path to a GCP service account json credentials file.
|
||||||
|
*/
|
||||||
|
public Credentials(String credentialsJsonFile) throws IOException {
|
||||||
|
this.credentialsJsonFile = credentialsJsonFile;
|
||||||
|
activateGoogleCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activateGoogleCredentials() throws IOException {
|
||||||
|
googleCredential = GoogleCredential
|
||||||
|
.fromStream(new FileInputStream(credentialsJsonFile))
|
||||||
|
.createScoped(SCOPES);
|
||||||
|
googleCredential.refreshToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provides an Oauth2 Access Token that can be used to make GCP service calls.*/
|
||||||
|
public String getAccessToken() throws IOException {
|
||||||
|
if (accessToken == null
|
||||||
|
|| googleCredential.getExpiresInSeconds() <= MIN_ACCESS_TOKEN_REFRESH_SEC) {
|
||||||
|
googleCredential.refreshToken();
|
||||||
|
accessToken = googleCredential.getAccessToken();
|
||||||
|
logger.log(Level.INFO, "Getting new access token.");
|
||||||
|
}
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
tools/published_devices_client/interfaces/BUILD
Normal file
17
tools/published_devices_client/interfaces/BUILD
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright 2018 Google LLC. All rights reserved.
|
||||||
|
# Desciption:
|
||||||
|
# JTS interfaces.
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_library(
|
||||||
|
name = "interfaces",
|
||||||
|
srcs = glob(["*.java"]),
|
||||||
|
deps = [
|
||||||
|
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||||
|
"@com_google_protobuf//:protobuf_java",
|
||||||
|
"@apache_httpcore//:org_apache_httpcomponents_httpcore",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
package com.google.video.widevine.jts.interfaces;
|
||||||
|
|
||||||
|
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeviceCertificate defines APIs for getting PublishedDevices and Published Devices list.
|
||||||
|
*/
|
||||||
|
public interface DeviceCertificate {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest {@code PublishedDevices} containing Published Devices list data.
|
||||||
|
*
|
||||||
|
* @return {@code PublishedDevices} containing Published Devices list data.
|
||||||
|
*/
|
||||||
|
public PublishedDevices getPublishedDevices() throws Exception;
|
||||||
|
|
||||||
|
}
|
||||||
37
tools/published_devices_client/providers/BUILD
Normal file
37
tools/published_devices_client/providers/BUILD
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Copyright 2018 Google LLC. All rights reserved.
|
||||||
|
# Desciption:
|
||||||
|
# JTS interfaces.
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_library(
|
||||||
|
name = "providers",
|
||||||
|
srcs = glob(["*.java"]),
|
||||||
|
runtime_deps = [
|
||||||
|
"@grpc_context//:io_grpc_grpc_context",
|
||||||
|
"@grpc_netty_all//:io_netty_netty_all",
|
||||||
|
"@io_perfmark_api//:io_perfmark_perfmark_api",
|
||||||
|
"@netty_boringssl//:io_netty_netty_tcnative_boringssl_static",
|
||||||
|
"@open_census//:io_opencensus_opencensus_contrib_http_jetty_client",
|
||||||
|
"@open_census_api//:io_opencensus_opencensus_api",
|
||||||
|
"@open_census_grpc_metrics//:io_opencensus_opencensus_contrib_grpc_metrics",
|
||||||
|
"@open_census_util//:io_opencensus_opencensus_contrib_http_util",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
":libwidevine_license_wvpl_sdk_lib.jar",
|
||||||
|
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_grpc",
|
||||||
|
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||||
|
"//httpclient",
|
||||||
|
"//interfaces",
|
||||||
|
"@google_guice//:com_google_inject_guice",
|
||||||
|
"@json//:org_json_json",
|
||||||
|
"@com_google_protobuf//:protobuf_java",
|
||||||
|
"@google_guava//:com_google_guava_guava",
|
||||||
|
"@grpc_core//:io_grpc_grpc_core",
|
||||||
|
"@grpc_netty//:io_grpc_grpc_netty",
|
||||||
|
"@grpc_stub//:io_grpc_grpc_stub",
|
||||||
|
"@io_grpc_grpc_java//api",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
// Copyright 2020 Google LLC. All rights reserved.
|
||||||
|
|
||||||
|
package com.google.video.widevine.jts.providers;
|
||||||
|
|
||||||
|
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||||
|
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevicesRequest;
|
||||||
|
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevicesServiceGrpc;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.protobuf.TextFormat;
|
||||||
|
import com.google.video.widevine.jts.httpclient.Credentials;
|
||||||
|
import com.google.video.widevine.jts.interfaces.DeviceCertificate;
|
||||||
|
import com.google.video.widevine.sdk.wvpl.WvPLBaseEnvironment;
|
||||||
|
import com.google.video.widevine.sdk.wvpl.WvPLStatusException;
|
||||||
|
import io.grpc.ManagedChannel;
|
||||||
|
import io.grpc.Metadata;
|
||||||
|
import io.grpc.netty.NettyChannelBuilder;
|
||||||
|
import io.grpc.stub.MetadataUtils;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the latest {@code PublishedDevices} data from the Widevine Published Devices Service.
|
||||||
|
*
|
||||||
|
* This implementation uses the Widevine Published Devices API, and support a gRPC method for
|
||||||
|
* retrieving PublishedDevices with an embedded Published Devices list.
|
||||||
|
*/
|
||||||
|
public class PublishedDevicesProvider implements DeviceCertificate {
|
||||||
|
private static final Logger logger = Logger.getLogger(PublishedDevicesProvider.class.getName());
|
||||||
|
private WvPLBaseEnvironment<?> environment = null;
|
||||||
|
private String apiServicePath = null;
|
||||||
|
private Credentials credentials = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PublishedDevicesProvider constructor.
|
||||||
|
*
|
||||||
|
* @param environment A WvPLBaseEnvironment object initialized with a Service Certificate.
|
||||||
|
* @param serviceAccountPath Path to a GCP Service Account json file, used in OAUTH.
|
||||||
|
* @param apiServicePath Path to a Widevine Published Devices API service.
|
||||||
|
* @throws IOException upon failure creating OAUTH credentials.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
public PublishedDevicesProvider(
|
||||||
|
WvPLBaseEnvironment<?> environment, String serviceAccountPath, String apiServicePath)
|
||||||
|
throws IOException {
|
||||||
|
this.environment = environment;
|
||||||
|
this.apiServicePath = apiServicePath;
|
||||||
|
credentials = new Credentials(serviceAccountPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest {@code PublishedDevices} from the Widevine Published Devices Service.
|
||||||
|
*
|
||||||
|
* @return The latest {@code PublishedDevices} data.
|
||||||
|
* @throws InterruptedException upon RPC failure.
|
||||||
|
* @throws WvPLStatusException upon WvPLBaseEnvironment errors.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public PublishedDevices getPublishedDevices() throws InterruptedException, WvPLStatusException{
|
||||||
|
ManagedChannel channel = null;
|
||||||
|
PublishedDevices devicesResponse = null;
|
||||||
|
|
||||||
|
logger.log(Level.INFO, "Getting PublishedDevices...");
|
||||||
|
try {
|
||||||
|
channel = createRpcChannel(apiServicePath);
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
String token = "Bearer " + credentials.getAccessToken();
|
||||||
|
metadata.put(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER), token);
|
||||||
|
PublishedDevicesServiceGrpc.PublishedDevicesServiceBlockingStub blockingStub =
|
||||||
|
PublishedDevicesServiceGrpc.newBlockingStub(channel)
|
||||||
|
.withInterceptors(MetadataUtils.newAttachHeadersInterceptor(metadata));
|
||||||
|
devicesResponse = blockingStub.getPublishedDevices(PublishedDevicesRequest.parseFrom(
|
||||||
|
environment.generateDeviceStatusListRequest()));
|
||||||
|
logger.log(Level.INFO, "GRPC Call to PublishedDevicesService.GetSignedList returned:\n %s"
|
||||||
|
+ TextFormat.printer().printToString(devicesResponse));
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.log(Level.INFO, "IOException encountered trying to retrieve the signed list: " + e);
|
||||||
|
} finally {
|
||||||
|
if (channel != null) {
|
||||||
|
channel.shutdown();
|
||||||
|
channel.awaitTermination(1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return devicesResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ManagedChannel createRpcChannel(String host) {
|
||||||
|
return NettyChannelBuilder.forTarget(host).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
39
tools/published_devices_client/tools/BUILD
Normal file
39
tools/published_devices_client/tools/BUILD
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Copyright 2019 Google LLC. All rights reserved.
|
||||||
|
# Desciption:
|
||||||
|
# JTS tools.
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
java_library(
|
||||||
|
name = "published_devices_cli_lib",
|
||||||
|
srcs = [
|
||||||
|
"PublishedDevicesCli.java",
|
||||||
|
],
|
||||||
|
runtime_deps = [
|
||||||
|
"@grpc_context//:io_grpc_grpc_context",
|
||||||
|
"@grpc_netty_all//:io_netty_netty_all",
|
||||||
|
"@io_perfmark_api//:io_perfmark_perfmark_api",
|
||||||
|
"@netty_boringssl//:io_netty_netty_tcnative_boringssl_static",
|
||||||
|
"@netty_tcnative//:io_netty_netty_tcnative",
|
||||||
|
"@open_census//:io_opencensus_opencensus_contrib_http_jetty_client",
|
||||||
|
"@open_census_api//:io_opencensus_opencensus_api",
|
||||||
|
"@open_census_grpc_metrics//:io_opencensus_opencensus_contrib_grpc_metrics",
|
||||||
|
"@open_census_util//:io_opencensus_opencensus_contrib_http_util",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_grpc",
|
||||||
|
"//google/chrome/widevine/contentpartners/v1beta1:published_devices_java_proto",
|
||||||
|
"//providers",
|
||||||
|
"//providers:libwidevine_license_wvpl_sdk_lib.jar",
|
||||||
|
"@jcommander//:com_beust_jcommander",
|
||||||
|
"@google_guava//:com_google_guava_guava",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_binary(
|
||||||
|
name = "published_devices_cli",
|
||||||
|
main_class = "com.google.video.widevine.jts.tools.PublishedDevicesCli",
|
||||||
|
runtime_deps = [
|
||||||
|
":published_devices_cli_lib",
|
||||||
|
],
|
||||||
|
)
|
||||||
140
tools/published_devices_client/tools/PublishedDevicesCli.java
Normal file
140
tools/published_devices_client/tools/PublishedDevicesCli.java
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
// Copyright 2020 Google LLC. All rights reserved.
|
||||||
|
|
||||||
|
package com.google.video.widevine.jts.tools;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
import com.beust.jcommander.JCommander;
|
||||||
|
import com.beust.jcommander.Parameter;
|
||||||
|
import com.google.chrome.widevine.contentpartners.v1beta1.PublishedDevices;
|
||||||
|
import com.google.common.io.BaseEncoding;
|
||||||
|
import com.google.video.widevine.jts.providers.PublishedDevicesProvider;
|
||||||
|
import com.google.video.widevine.sdk.wvpl.WvPLEnvironment;
|
||||||
|
import com.google.video.widevine.sdk.wvpl.WvPLStatus;
|
||||||
|
import com.google.video.widevine.sdk.wvpl.WvPLStatusException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Published Devices Command Line Interface.
|
||||||
|
*
|
||||||
|
* Provides a command line interface to get the latest {@code PublishedDevices} data from the
|
||||||
|
* Widevine Published Devices Service.
|
||||||
|
*
|
||||||
|
* Default Widevine Service API path: widevine.googleapis.com.
|
||||||
|
*
|
||||||
|
* To build:
|
||||||
|
* Bazel build java/com/google/video/widevine/jts/tools:published_devices_client_deploy.jar
|
||||||
|
*
|
||||||
|
* To run:
|
||||||
|
* java -Djava.library.path=./path/to/license/sdk.so \
|
||||||
|
* -jar /path/to/published_devices_client_deploy.jar \
|
||||||
|
* -service_cert_path /path/to/cert_file.der \
|
||||||
|
* -service_private_key_path /path/to/private_key.der \
|
||||||
|
* -service_private_key_passphrase theprivatekeypassphrase
|
||||||
|
* -service_account_path /path/to/service-account.json \
|
||||||
|
*/
|
||||||
|
public final class PublishedDevicesCli {
|
||||||
|
private WvPLEnvironment environment = null;
|
||||||
|
private PublishedDevicesProvider publishedDevices = null;
|
||||||
|
private String serviceCertPath = null;
|
||||||
|
private String privateKeyPath = null;
|
||||||
|
private String privateKeyPassphrase = null;
|
||||||
|
|
||||||
|
/** Command Line Flags. */
|
||||||
|
static class Flags{
|
||||||
|
private Flags() {}
|
||||||
|
|
||||||
|
@Parameter(names = "-service_cert_path", description = "Path to service certificate")
|
||||||
|
private String serviceCertPath = "";
|
||||||
|
|
||||||
|
@Parameter(names = "-service_private_key_path",
|
||||||
|
description = "Path to private key file needed to decrypt service certificate")
|
||||||
|
private String servicePrivateKeyPath = "";
|
||||||
|
|
||||||
|
@Parameter(names = "-service_private_key_passphrase",
|
||||||
|
description = "Passphrase needed to decrypt the private key")
|
||||||
|
private String servicePrivateKeyPassphrase = "";
|
||||||
|
|
||||||
|
@Parameter(names = "-service_account_path",
|
||||||
|
description = "Path to a GCP Service Account json file")
|
||||||
|
private String serviceAccountPath = "";
|
||||||
|
|
||||||
|
@Parameter(names = "-api_service_path",
|
||||||
|
description = "Optional. Path to a Widevine API service.")
|
||||||
|
private String apiServicePath = "widevine.googleapis.com";
|
||||||
|
|
||||||
|
@Parameter(names = "-s",
|
||||||
|
description = "Save PublishedDevices file path.")
|
||||||
|
private String saveFilePath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublishedDevicesCli(String serviceCertPath, String privateKeyPath,
|
||||||
|
String privateKeyPassphrase, String serviceAccountPath, String apiServicePath)
|
||||||
|
throws Exception {
|
||||||
|
this.serviceCertPath = serviceCertPath;
|
||||||
|
this.privateKeyPath = privateKeyPath;
|
||||||
|
this.privateKeyPassphrase = privateKeyPassphrase;
|
||||||
|
initializeWvplEnvironment();
|
||||||
|
publishedDevices = new PublishedDevicesProvider(
|
||||||
|
environment, serviceAccountPath, apiServicePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest {@code PublishedDevices} from the Widevine Published Devices Service.
|
||||||
|
*
|
||||||
|
* @return The latest PublishedDevices data.
|
||||||
|
* @throws InterruptedException upon RPC failure.
|
||||||
|
* @throws WvPLStatusException upon WvPLBaseEnvironment errors.
|
||||||
|
*/
|
||||||
|
public PublishedDevices getPublishedDevices() throws InterruptedException, WvPLStatusException {
|
||||||
|
return publishedDevices.getPublishedDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves PublishedDevices proto data to a file.
|
||||||
|
*
|
||||||
|
* @param saveFilePath The path to the save file.
|
||||||
|
* @param publishedDevices A PublishedDevices proto.
|
||||||
|
*/
|
||||||
|
public static void savePublishedDevicesDataToFile(String saveFilePath,
|
||||||
|
PublishedDevices publishedDevices) throws IOException {
|
||||||
|
Files.write(
|
||||||
|
Paths.get(saveFilePath),
|
||||||
|
BaseEncoding.base64Url().encode(publishedDevices.toByteArray()).getBytes(UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Flags flags = new Flags();
|
||||||
|
new JCommander(flags, args);
|
||||||
|
PublishedDevicesCli devices = new PublishedDevicesCli(
|
||||||
|
flags.serviceCertPath,
|
||||||
|
flags.servicePrivateKeyPath,
|
||||||
|
flags.servicePrivateKeyPassphrase,
|
||||||
|
flags.serviceAccountPath,
|
||||||
|
flags.apiServicePath);
|
||||||
|
PublishedDevices publishedDevices = devices.getPublishedDevices();
|
||||||
|
if (flags.saveFilePath != null) {
|
||||||
|
savePublishedDevicesDataToFile(flags.saveFilePath, publishedDevices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeWvplEnvironment() throws Exception {
|
||||||
|
environment = new WvPLEnvironment(new HashMap<>());
|
||||||
|
// Set service certificate.
|
||||||
|
WvPLStatus status =
|
||||||
|
environment.setServiceCertificate(
|
||||||
|
loadDataFromFile(serviceCertPath),
|
||||||
|
loadDataFromFile(privateKeyPath),
|
||||||
|
privateKeyPassphrase.getBytes(UTF_8));
|
||||||
|
if (!status.getStatusCode().equals(WvPLStatus.StatusCode.OK)) {
|
||||||
|
throw new Exception("Set server certificate status: " + status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] loadDataFromFile(String filePath) throws IOException {
|
||||||
|
return Files.readAllBytes(Paths.get(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user