google-api-go-client: add a client option for disabling the oc http and grpc middlewares.

Currently there is no way to disable or override the settings for the opencensus
middlewares that are wrapped around client http and grpc transports. This prevents
fixing issues like updating the operation name used for the spans generated by the
client. Because OC is global and automatically bound, there is no other work around
today to update these settings.

Fixes googleapis/google-cloud-go#1573

Change-Id: I9972018315fd3d4277faae166f3f0ac87073f32a
Reviewed-on: https://code-review.googlesource.com/c/google-api-go-client/+/46590
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chris Broadfoot <cbro@google.com>
Reviewed-by: Chris Cotter <cjcotter@google.com>
Reviewed-by: Tyler Bui-Palsulich <tbp@google.com>
Reviewed-by: Jean de Klerk <deklerk@google.com>
diff --git a/AUTHORS b/AUTHORS
index f73b725..f070290 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -8,3 +8,4 @@
 
 # Please keep the list sorted.
 Google Inc.
+LightStep Inc.
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index fe55ebf..788677b 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -45,6 +45,7 @@
 Johan Euphrosine <proppy@google.com>
 Kostik Shtoyk <kostik@google.com>
 Kunpei Sakai <namusyaka@gmail.com>
+Matthew Dolan <dolan@lightstep.com>
 Matthew Whisenhunt <matt.whisenhunt@gmail.com>
 Michael McGreevy <mcgreevy@golang.org>
 Nick Craig-Wood <nickcw@gmail.com>
diff --git a/internal/settings.go b/internal/settings.go
index dacdbf1..544d715 100644
--- a/internal/settings.go
+++ b/internal/settings.go
@@ -17,19 +17,20 @@
 // DialSettings holds information needed to establish a connection with a
 // Google API service.
 type DialSettings struct {
-	Endpoint        string
-	Scopes          []string
-	TokenSource     oauth2.TokenSource
-	Credentials     *google.Credentials
-	CredentialsFile string // if set, Token Source is ignored.
-	CredentialsJSON []byte
-	UserAgent       string
-	APIKey          string
-	Audiences       []string
-	HTTPClient      *http.Client
-	GRPCDialOpts    []grpc.DialOption
-	GRPCConn        *grpc.ClientConn
-	NoAuth          bool
+	Endpoint          string
+	Scopes            []string
+	TokenSource       oauth2.TokenSource
+	Credentials       *google.Credentials
+	CredentialsFile   string // if set, Token Source is ignored.
+	CredentialsJSON   []byte
+	UserAgent         string
+	APIKey            string
+	Audiences         []string
+	HTTPClient        *http.Client
+	GRPCDialOpts      []grpc.DialOption
+	GRPCConn          *grpc.ClientConn
+	NoAuth            bool
+	TelemetryDisabled bool
 
 	// Google API system parameters. For more information please read:
 	// https://cloud.google.com/apis/docs/system-parameters
diff --git a/option/option.go b/option/option.go
index 2326c9a..8a4cd16 100644
--- a/option/option.go
+++ b/option/option.go
@@ -223,3 +223,16 @@
 func (w withRequestReason) Apply(o *internal.DialSettings) {
 	o.RequestReason = string(w)
 }
+
+// WithTelemetryDisabled returns a ClientOption that disables default telemetry (OpenCensus)
+// settings on gRPC and HTTP clients.
+// An example reason would be to bind custom telemetry that overrides the defaults.
+func WithTelemetryDisabled() ClientOption {
+	return withTelemetryDisabledOption{}
+}
+
+type withTelemetryDisabledOption struct{}
+
+func (w withTelemetryDisabledOption) Apply(o *internal.DialSettings) {
+	o.TelemetryDisabled = true
+}
diff --git a/option/option_test.go b/option/option_test.go
index 8ae72cc..ec77fef 100644
--- a/option/option_test.go
+++ b/option/option_test.go
@@ -44,25 +44,27 @@
 		WithAudiences("https://example.com/"),
 		WithQuotaProject("user-project"),
 		WithRequestReason("Request Reason"),
+		WithTelemetryDisabled(),
 	}
 	var got internal.DialSettings
 	for _, opt := range opts {
 		opt.Apply(&got)
 	}
 	want := internal.DialSettings{
-		Scopes:          []string{"https://example.com/auth/helloworld", "https://example.com/auth/otherthing"},
-		UserAgent:       "ua",
-		Endpoint:        "https://example.com:443",
-		GRPCConn:        conn,
-		Credentials:     &google.DefaultCredentials{ProjectID: "p"},
-		CredentialsFile: "service-account.json",
-		CredentialsJSON: []byte(`{some: "json"}`),
-		APIKey:          "api-key",
-		Audiences:       []string{"https://example.com/"},
-		QuotaProject:    "user-project",
-		RequestReason:   "Request Reason",
+		Scopes:            []string{"https://example.com/auth/helloworld", "https://example.com/auth/otherthing"},
+		UserAgent:         "ua",
+		Endpoint:          "https://example.com:443",
+		GRPCConn:          conn,
+		Credentials:       &google.DefaultCredentials{ProjectID: "p"},
+		CredentialsFile:   "service-account.json",
+		CredentialsJSON:   []byte(`{some: "json"}`),
+		APIKey:            "api-key",
+		Audiences:         []string{"https://example.com/"},
+		QuotaProject:      "user-project",
+		RequestReason:     "Request Reason",
+		TelemetryDisabled: true,
 	}
 	if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(grpc.ClientConn{})) {
-		t.Errorf("\ngot  %#v\nwant %#v", got, want)
+		t.Errorf(cmp.Diff(got, want, cmpopts.IgnoreUnexported(grpc.ClientConn{})))
 	}
 }
diff --git a/transport/grpc/dial.go b/transport/grpc/dial.go
index dfc20a5..7526e68 100644
--- a/transport/grpc/dial.go
+++ b/transport/grpc/dial.go
@@ -108,7 +108,7 @@
 	// Add tracing, but before the other options, so that clients can override the
 	// gRPC stats handler.
 	// This assumes that gRPC options are processed in order, left to right.
-	grpcOpts = addOCStatsHandler(grpcOpts)
+	grpcOpts = addOCStatsHandler(grpcOpts, o)
 	grpcOpts = append(grpcOpts, o.GRPCDialOpts...)
 	if o.UserAgent != "" {
 		grpcOpts = append(grpcOpts, grpc.WithUserAgent(o.UserAgent))
@@ -125,7 +125,10 @@
 	return grpc.DialContext(ctx, o.Endpoint, grpcOpts...)
 }
 
-func addOCStatsHandler(opts []grpc.DialOption) []grpc.DialOption {
+func addOCStatsHandler(opts []grpc.DialOption, settings internal.DialSettings) []grpc.DialOption {
+	if settings.TelemetryDisabled {
+		return opts
+	}
 	return append(opts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
 }
 
diff --git a/transport/http/dial.go b/transport/http/dial.go
index 26c8d8a..1ef67ce 100644
--- a/transport/http/dial.go
+++ b/transport/http/dial.go
@@ -60,7 +60,7 @@
 		quotaProject:  settings.QuotaProject,
 		requestReason: settings.RequestReason,
 	}
-	trans = addOCTransport(trans)
+	trans = addOCTransport(trans, settings)
 	switch {
 	case settings.NoAuth:
 		// Do nothing.
@@ -142,7 +142,10 @@
 	return http.DefaultTransport
 }
 
-func addOCTransport(trans http.RoundTripper) http.RoundTripper {
+func addOCTransport(trans http.RoundTripper, settings *internal.DialSettings) http.RoundTripper {
+	if settings.TelemetryDisabled {
+		return trans
+	}
 	return &ochttp.Transport{
 		Base:        trans,
 		Propagation: &propagation.HTTPFormat{},