Merge "Change remaining properties to *string, *bool in Soong."
diff --git a/android/onceper.go b/android/onceper.go
index 5f7a310..f19f75c 100644
--- a/android/onceper.go
+++ b/android/onceper.go
@@ -15,12 +15,12 @@
 package android
 
 import (
+	"fmt"
 	"sync"
-	"sync/atomic"
 )
 
 type OncePer struct {
-	values     atomic.Value
+	values     sync.Map
 	valuesLock sync.Mutex
 }
 
@@ -29,33 +29,32 @@
 // Once computes a value the first time it is called with a given key per OncePer, and returns the
 // value without recomputing when called with the same key.  key must be hashable.
 func (once *OncePer) Once(key interface{}, value func() interface{}) interface{} {
-	// Atomically load the map without locking.  If this is the first call Load() will return nil
-	// and the type assertion will fail, leaving a nil map in m, but that's OK since m is only used
-	// for reads.
-	m, _ := once.values.Load().(valueMap)
-	if v, ok := m[key]; ok {
+	// Fast path: check if the key is already in the map
+	if v, ok := once.values.Load(key); ok {
 		return v
 	}
 
+	// Slow path: lock so that we don't call the value function twice concurrently
 	once.valuesLock.Lock()
 	defer once.valuesLock.Unlock()
 
 	// Check again with the lock held
-	m, _ = once.values.Load().(valueMap)
-	if v, ok := m[key]; ok {
+	if v, ok := once.values.Load(key); ok {
 		return v
 	}
 
-	// Copy the existing map
-	newMap := make(valueMap, len(m))
-	for k, v := range m {
-		newMap[k] = v
-	}
-
+	// Still not in the map, call the value function and store it
 	v := value()
+	once.values.Store(key, v)
 
-	newMap[key] = v
-	once.values.Store(newMap)
+	return v
+}
+
+func (once *OncePer) Get(key interface{}) interface{} {
+	v, ok := once.values.Load(key)
+	if !ok {
+		panic(fmt.Errorf("Get() called before Once()"))
+	}
 
 	return v
 }
diff --git a/android/register.go b/android/register.go
index 51089f7..81a266d 100644
--- a/android/register.go
+++ b/android/register.go
@@ -31,6 +31,7 @@
 }
 
 var singletons []singleton
+var preSingletons []singleton
 
 type mutator struct {
 	name            string
@@ -60,6 +61,10 @@
 	singletons = append(singletons, singleton{name, factory})
 }
 
+func RegisterPreSingletonType(name string, factory blueprint.SingletonFactory) {
+	preSingletons = append(preSingletons, singleton{name, factory})
+}
+
 type Context struct {
 	*blueprint.Context
 }
@@ -69,6 +74,10 @@
 }
 
 func (ctx *Context) Register() {
+	for _, t := range preSingletons {
+		ctx.RegisterPreSingletonType(t.name, t.factory)
+	}
+
 	for _, t := range moduleTypes {
 		ctx.RegisterModuleType(t.name, t.factory)
 	}
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 6f08fa9..2345ebc 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -100,9 +100,6 @@
 		// http://b/68236239 Allow 0/NULL instead of using nullptr everywhere.
 		"-Wno-zero-as-null-pointer-constant",
 
-		// http://b/68236396 Allow unknown warning options.
-		"-Wno-unknown-warning-option",
-
 		// http://b/36463318 Clang executes with an absolute path, so clang-provided
 		// headers are now absolute.
 		"-fdebug-prefix-map=$$PWD/=",
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index e4a05fc..183f800 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -15,7 +15,6 @@
 package main
 
 import (
-	"bytes"
 	"context"
 	"flag"
 	"fmt"
@@ -280,7 +279,7 @@
 				log.Fatalf("Error creating std.log: %v", err)
 			}
 
-			productLog := logger.New(&bytes.Buffer{})
+			productLog := logger.New(f)
 			productLog.SetOutput(filepath.Join(productLogDir, "soong.log"))
 
 			productCtx := build.Context{&build.ContextImpl{
diff --git a/cmd/pom2mk/pom2mk.go b/cmd/pom2mk/pom2mk.go
index ac29a2a..4596db9 100644
--- a/cmd/pom2mk/pom2mk.go
+++ b/cmd/pom2mk/pom2mk.go
@@ -83,6 +83,7 @@
 
 var extraDeps = make(ExtraDeps)
 
+var sdkVersion string
 var useVersion string
 
 type Dependency struct {
@@ -127,6 +128,10 @@
 	return ret
 }
 
+func (p Pom) SdkVersion() string {
+	return sdkVersion
+}
+
 func (p *Pom) FixDepTypes(modules map[string]*Pom) {
 	for _, d := range p.Dependencies {
 		if d.Type != "" {
@@ -147,6 +152,7 @@
 LOCAL_BUILT_MODULE_STEM := javalib.jar
 LOCAL_MODULE_SUFFIX := .{{.Packaging}}
 LOCAL_USE_AAPT2 := true
+LOCAL_SDK_VERSION := {{.SdkVersion}}
 LOCAL_STATIC_ANDROID_LIBRARIES := \
 {{range .MkDeps}}  {{.}} \
 {{end}}
@@ -196,6 +202,8 @@
      Some Android.mk modules have transitive dependencies that must be specified when they are
      depended upon (like android-support-v7-mediarouter requires android-support-v7-appcompat).
      This may be specified multiple times to declare these dependencies.
+  -sdk-version <version>
+     Sets LOCAL_SDK_VERSION := <version> for all modules.
   -use-version <version>
      If the maven directory contains multiple versions of artifacts and their pom files,
      -use-version can be used to only write makefiles for a specific version of those artifacts.
@@ -208,6 +216,7 @@
 
 	flag.Var(&extraDeps, "extra-deps", "Extra dependencies needed when depending on a module")
 	flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
+	flag.StringVar(&sdkVersion, "sdk-version", "", "What to write to LOCAL_SDK_VERSION")
 	flag.StringVar(&useVersion, "use-version", "", "Only read artifacts of a specific version")
 	flag.Parse()