GVR SDK Android 1.200
diff --git a/.gitignore b/.gitignore
index 3426397..098b0f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,4 @@
 local.properties
 
 # OS configurations.
-.DS_Store
+.DS_Store
\ No newline at end of file
diff --git a/README.md b/README.md
index ee82125..6d9f52d 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,13 @@
 
 Enables Daydream and Cardboard app development on Android.
 
-Copyright (c) 2016 Google Inc. All rights reserved.
+Copyright (c) 2018 Google Inc.
+
+See [https://developers.google.com/terms/](https://developers.google.com/terms/)
+for the **Google APIs Terms of Service** which cover this SDK. The code in
+`samples` is covered by the Apache 2 `LICENSE` file in that directory, and the
+files in `assets` are covered by Creative Commons `LICENSE` file in that
+directory.
 
 For updates, known issues, and upgrade instructions, see the
 [release-notes](//github.com/googlevr/gvr-android-sdk/releases).
diff --git a/apks/controller_emulator.apk b/apks/controller_emulator.apk
index d665a36..d4b4cad 100644
--- a/apks/controller_emulator.apk
+++ b/apks/controller_emulator.apk
Binary files differ
diff --git a/assets/LICENSE b/assets/LICENSE
new file mode 100644
index 0000000..dc8853a
--- /dev/null
+++ b/assets/LICENSE
@@ -0,0 +1,393 @@
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+     Considerations for licensors: Our public licenses are
+     intended for use by those authorized to give the public
+     permission to use material in ways otherwise restricted by
+     copyright and certain other rights. Our licenses are
+     irrevocable. Licensors should read and understand the terms
+     and conditions of the license they choose before applying it.
+     Licensors should also secure all rights necessary before
+     applying our licenses so that the public can reuse the
+     material as expected. Licensors should clearly mark any
+     material not subject to the license. This includes other CC-
+     licensed material, or material used under an exception or
+     limitation to copyright. More considerations for licensors:
+	wiki.creativecommons.org/Considerations_for_licensors
+
+     Considerations for the public: By using one of our public
+     licenses, a licensor grants the public permission to use the
+     licensed material under specified terms and conditions. If
+     the licensor's permission is not necessary for any reason--for
+     example, because of any applicable exception or limitation to
+     copyright--then that use is not regulated by the license. Our
+     licenses grant only permissions under copyright and certain
+     other rights that a licensor has authority to grant. Use of
+     the licensed material may still be restricted for other
+     reasons, including because others have copyright or other
+     rights in the material. A licensor may make special requests,
+     such as asking that all changes be marked or described.
+     Although not required by our licenses, you are encouraged to
+     respect those requests where reasonable. More_considerations
+     for the public: 
+	wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+  a. Adapted Material means material subject to Copyright and Similar
+     Rights that is derived from or based upon the Licensed Material
+     and in which the Licensed Material is translated, altered,
+     arranged, transformed, or otherwise modified in a manner requiring
+     permission under the Copyright and Similar Rights held by the
+     Licensor. For purposes of this Public License, where the Licensed
+     Material is a musical work, performance, or sound recording,
+     Adapted Material is always produced where the Licensed Material is
+     synched in timed relation with a moving image.
+
+  b. Adapter's License means the license You apply to Your Copyright
+     and Similar Rights in Your contributions to Adapted Material in
+     accordance with the terms and conditions of this Public License.
+
+  c. Copyright and Similar Rights means copyright and/or similar rights
+     closely related to copyright including, without limitation,
+     performance, broadcast, sound recording, and Sui Generis Database
+     Rights, without regard to how the rights are labeled or
+     categorized. For purposes of this Public License, the rights
+     specified in Section 2(b)(1)-(2) are not Copyright and Similar
+     Rights.
+
+  d. Effective Technological Measures means those measures that, in the
+     absence of proper authority, may not be circumvented under laws
+     fulfilling obligations under Article 11 of the WIPO Copyright
+     Treaty adopted on December 20, 1996, and/or similar international
+     agreements.
+
+  e. Exceptions and Limitations means fair use, fair dealing, and/or
+     any other exception or limitation to Copyright and Similar Rights
+     that applies to Your use of the Licensed Material.
+
+  f. Licensed Material means the artistic or literary work, database,
+     or other material to which the Licensor applied this Public
+     License.
+
+  g. Licensed Rights means the rights granted to You subject to the
+     terms and conditions of this Public License, which are limited to
+     all Copyright and Similar Rights that apply to Your use of the
+     Licensed Material and that the Licensor has authority to license.
+
+  h. Licensor means the individual(s) or entity(ies) granting rights
+     under this Public License.
+
+  i. Share means to provide material to the public by any means or
+     process that requires permission under the Licensed Rights, such
+     as reproduction, public display, public performance, distribution,
+     dissemination, communication, or importation, and to make material
+     available to the public including in ways that members of the
+     public may access the material from a place and at a time
+     individually chosen by them.
+
+  j. Sui Generis Database Rights means rights other than copyright
+     resulting from Directive 96/9/EC of the European Parliament and of
+     the Council of 11 March 1996 on the legal protection of databases,
+     as amended and/or succeeded, as well as other essentially
+     equivalent rights anywhere in the world.
+
+  k. You means the individual or entity exercising the Licensed Rights
+     under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+  a. License grant.
+
+       1. Subject to the terms and conditions of this Public License,
+          the Licensor hereby grants You a worldwide, royalty-free,
+          non-sublicensable, non-exclusive, irrevocable license to
+          exercise the Licensed Rights in the Licensed Material to:
+
+            a. reproduce and Share the Licensed Material, in whole or
+               in part; and
+
+            b. produce, reproduce, and Share Adapted Material.
+
+       2. Exceptions and Limitations. For the avoidance of doubt, where
+          Exceptions and Limitations apply to Your use, this Public
+          License does not apply, and You do not need to comply with
+          its terms and conditions.
+
+       3. Term. The term of this Public License is specified in Section
+          6(a).
+
+       4. Media and formats; technical modifications allowed. The
+          Licensor authorizes You to exercise the Licensed Rights in
+          all media and formats whether now known or hereafter created,
+          and to make technical modifications necessary to do so. The
+          Licensor waives and/or agrees not to assert any right or
+          authority to forbid You from making technical modifications
+          necessary to exercise the Licensed Rights, including
+          technical modifications necessary to circumvent Effective
+          Technological Measures. For purposes of this Public License,
+          simply making modifications authorized by this Section 2(a)
+          (4) never produces Adapted Material.
+
+       5. Downstream recipients.
+
+            a. Offer from the Licensor -- Licensed Material. Every
+               recipient of the Licensed Material automatically
+               receives an offer from the Licensor to exercise the
+               Licensed Rights under the terms and conditions of this
+               Public License.
+
+            b. No downstream restrictions. You may not offer or impose
+               any additional or different terms or conditions on, or
+               apply any Effective Technological Measures to, the
+               Licensed Material if doing so restricts exercise of the
+               Licensed Rights by any recipient of the Licensed
+               Material.
+
+       6. No endorsement. Nothing in this Public License constitutes or
+          may be construed as permission to assert or imply that You
+          are, or that Your use of the Licensed Material is, connected
+          with, or sponsored, endorsed, or granted official status by,
+          the Licensor or others designated to receive attribution as
+          provided in Section 3(a)(1)(A)(i).
+
+  b. Other rights.
+
+       1. Moral rights, such as the right of integrity, are not
+          licensed under this Public License, nor are publicity,
+          privacy, and/or other similar personality rights; however, to
+          the extent possible, the Licensor waives and/or agrees not to
+          assert any such rights held by the Licensor to the limited
+          extent necessary to allow You to exercise the Licensed
+          Rights, but not otherwise.
+
+       2. Patent and trademark rights are not licensed under this
+          Public License.
+
+       3. To the extent possible, the Licensor waives any right to
+          collect royalties from You for the exercise of the Licensed
+          Rights, whether directly or through a collecting society
+          under any voluntary or waivable statutory or compulsory
+          licensing scheme. In all other cases the Licensor expressly
+          reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+  a. Attribution.
+
+       1. If You Share the Licensed Material (including in modified
+          form), You must:
+
+            a. retain the following if it is supplied by the Licensor
+               with the Licensed Material:
+
+                 i. identification of the creator(s) of the Licensed
+                    Material and any others designated to receive
+                    attribution, in any reasonable manner requested by
+                    the Licensor (including by pseudonym if
+                    designated);
+
+                ii. a copyright notice;
+
+               iii. a notice that refers to this Public License;
+
+                iv. a notice that refers to the disclaimer of
+                    warranties;
+
+                 v. a URI or hyperlink to the Licensed Material to the
+                    extent reasonably practicable;
+
+            b. indicate if You modified the Licensed Material and
+               retain an indication of any previous modifications; and
+
+            c. indicate the Licensed Material is licensed under this
+               Public License, and include the text of, or the URI or
+               hyperlink to, this Public License.
+
+       2. You may satisfy the conditions in Section 3(a)(1) in any
+          reasonable manner based on the medium, means, and context in
+          which You Share the Licensed Material. For example, it may be
+          reasonable to satisfy the conditions by providing a URI or
+          hyperlink to a resource that includes the required
+          information.
+
+       3. If requested by the Licensor, You must remove any of the
+          information required by Section 3(a)(1)(A) to the extent
+          reasonably practicable.
+
+       4. If You Share Adapted Material You produce, the Adapter's
+          License You apply must not prevent recipients of the Adapted
+          Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+     to extract, reuse, reproduce, and Share all or a substantial
+     portion of the contents of the database;
+
+  b. if You include all or a substantial portion of the database
+     contents in a database in which You have Sui Generis Database
+     Rights, then the database in which You have Sui Generis Database
+     Rights (but not its individual contents) is Adapted Material; and
+
+  c. You must comply with the conditions in Section 3(a) if You Share
+     all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+  c. The disclaimer of warranties and limitation of liability provided
+     above shall be interpreted in a manner that, to the extent
+     possible, most closely approximates an absolute disclaimer and
+     waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+  a. This Public License applies for the term of the Copyright and
+     Similar Rights licensed here. However, if You fail to comply with
+     this Public License, then Your rights under this Public License
+     terminate automatically.
+
+  b. Where Your right to use the Licensed Material has terminated under
+     Section 6(a), it reinstates:
+
+       1. automatically as of the date the violation is cured, provided
+          it is cured within 30 days of Your discovery of the
+          violation; or
+
+       2. upon express reinstatement by the Licensor.
+
+     For the avoidance of doubt, this Section 6(b) does not affect any
+     right the Licensor may have to seek remedies for Your violations
+     of this Public License.
+
+  c. For the avoidance of doubt, the Licensor may also offer the
+     Licensed Material under separate terms or conditions or stop
+     distributing the Licensed Material at any time; however, doing so
+     will not terminate this Public License.
+
+  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+     License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+  a. The Licensor shall not be bound by any additional or different
+     terms or conditions communicated by You unless expressly agreed.
+
+  b. Any arrangements, understandings, or agreements regarding the
+     Licensed Material not stated herein are separate from and
+     independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+  a. For the avoidance of doubt, this Public License does not, and
+     shall not be interpreted to, reduce, limit, restrict, or impose
+     conditions on any use of the Licensed Material that could lawfully
+     be made without permission under this Public License.
+
+  b. To the extent possible, if any provision of this Public License is
+     deemed unenforceable, it shall be automatically reformed to the
+     minimum extent necessary to make it enforceable. If the provision
+     cannot be reformed, it shall be severed from this Public License
+     without affecting the enforceability of the remaining terms and
+     conditions.
+
+  c. No term or condition of this Public License will be waived and no
+     failure to comply consented to unless expressly agreed to by the
+     Licensor.
+
+  d. Nothing in this Public License constitutes or may be interpreted
+     as a limitation upon, or waiver of, any privileges and immunities
+     that apply to the Licensor or You, including from the legal
+     processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public licenses.
+Notwithstanding, Creative Commons may elect to apply one of its public
+licenses to material it publishes and in those instances will be
+considered the "Licensor." Except for the limited purpose of indicating
+that material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the public
+licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/build.gradle b/build.gradle
index 6cf3dba..38cc62c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.0.1'
+        classpath 'com.android.tools.build:gradle:3.3.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -35,7 +35,7 @@
 // The dependencies for NDK builds live inside the .aar files so they need to
 // be extracted before NDK targets can build.
 task extractNdk(type: Copy)  {
-    from zipTree("${project.rootDir}/libraries/sdk-base-1.190.0.aar")
+    from zipTree("${project.rootDir}/libraries/sdk-base-1.200.0.aar")
     into "${project.rootDir}/libraries/"
     include "headers/vr/gvr/capi/**/*h"
     include "jni/**/libgvr_audio.so"
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0d0b041..ad2a4c7 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-bin.zip
diff --git a/libraries/sdk-audio-1.190.0.pom b/libraries/sdk-audio-1.190.0.pom
index 8dd6415..5588695 100644
--- a/libraries/sdk-audio-1.190.0.pom
+++ b/libraries/sdk-audio-1.190.0.pom
@@ -4,7 +4,7 @@
 
   <groupId>com.google.vr</groupId>
   <artifactId>sdk-audio</artifactId>
-  <version>1.190.0</version>
+  <version>1.200.0</version>
   <packaging>aar</packaging>
 
   <name>Google VR SDK-Audio</name>
@@ -19,7 +19,7 @@
       <groupId>com.google.vr</groupId>
       <artifactId>sdk-base</artifactId>
       <type>aar</type>
-      <version>1.190.0</version>
+      <version>1.200.0</version>
     </dependency>
   </dependencies>
 </project>
diff --git a/libraries/sdk-base-1.190.0.aar b/libraries/sdk-base-1.190.0.aar
deleted file mode 100644
index beb4a2d..0000000
--- a/libraries/sdk-base-1.190.0.aar
+++ /dev/null
Binary files differ
diff --git a/libraries/sdk-base-1.200.0.aar b/libraries/sdk-base-1.200.0.aar
new file mode 100644
index 0000000..3be3946
--- /dev/null
+++ b/libraries/sdk-base-1.200.0.aar
Binary files differ
diff --git a/libraries/sdk-base-1.190.0.pom b/libraries/sdk-base-1.200.0.pom
similarity index 94%
rename from libraries/sdk-base-1.190.0.pom
rename to libraries/sdk-base-1.200.0.pom
index fa7bc08..0214731 100644
--- a/libraries/sdk-base-1.190.0.pom
+++ b/libraries/sdk-base-1.200.0.pom
@@ -4,7 +4,7 @@
 
   <groupId>com.google.vr</groupId>
   <artifactId>sdk-base</artifactId>
-  <version>1.190.0</version>
+  <version>1.200.0</version>
   <packaging>aar</packaging>
 
   <name>Google VR SDK-Base</name>
diff --git a/proguard-gvr.txt b/proguard-gvr.txt
index 7ee4e8a..a66da44 100644
--- a/proguard-gvr.txt
+++ b/proguard-gvr.txt
@@ -8,8 +8,14 @@
     native <methods>;
 }
 
-# The SDK configuration class member names are useful for debugging client logs.
--keepclasseswithmembernames,allowoptimization class com.google.common.logging.nano.Vr$VREvent$SdkConfigurationParams** {
+# The SDK configuration protos use reflection.
+-keep class com.google.vr.sdk.proto.** {
+    *;
+}
+-keep class com.google.common.logging.Vr$VREvent$SdkConfigurationParams** {
+    *;
+}
+-keep class com.google.common.logging.nano.Vr$VREvent$SdkConfigurationParams** {
     *;
 }
 
diff --git a/samples/LICENSE b/samples/LICENSE
new file mode 100644
index 0000000..3037da8
--- /dev/null
+++ b/samples/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2018 Google, Inc.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/samples/ndk-hellovr/build.gradle b/samples/ndk-hellovr/build.gradle
index 241663b..ac1a6c8 100644
--- a/samples/ndk-hellovr/build.gradle
+++ b/samples/ndk-hellovr/build.gradle
@@ -21,7 +21,7 @@
     defaultConfig {
         applicationId "com.google.vr.ndk.samples.hellovr"
         minSdkVersion 19
-        targetSdkVersion 24
+        targetSdkVersion 26
         versionCode 1
         versionName "1.0"
         externalNativeBuild {
@@ -57,7 +57,7 @@
 }
 
 dependencies {
-    implementation 'com.google.vr:sdk-base:1.190.0'
+    implementation 'com.google.vr:sdk-base:1.200.0'
 }
 
 build.dependsOn(':extractNdk')
diff --git a/samples/ndk-hellovr/src/main/AndroidManifest.xml b/samples/ndk-hellovr/src/main/AndroidManifest.xml
index 81c6d9b..3d6a828 100644
--- a/samples/ndk-hellovr/src/main/AndroidManifest.xml
+++ b/samples/ndk-hellovr/src/main/AndroidManifest.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.google.vr.ndk.samples.hellovr"
-    android:versionCode="181016016"
-    android:versionName="1.190.0">
+    android:versionCode="190204066"
+    android:versionName="1.200.0">
 
   <!-- The GVR SDK requires API 19+ and OpenGL ES 2+. -->
-  <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24" />
+
   <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
   <!-- Required for vibration feedback when the trigger action is performed. -->
diff --git a/samples/ndk-hellovrbeta/build.gradle b/samples/ndk-hellovrbeta/build.gradle
index 7f1d69e..42b02ea 100644
--- a/samples/ndk-hellovrbeta/build.gradle
+++ b/samples/ndk-hellovrbeta/build.gradle
@@ -13,15 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 apply plugin: 'com.android.application'
 
 android {
     compileSdkVersion 26
     defaultConfig {
         applicationId "com.google.vr.ndk.samples.hellovrbeta"
-        minSdkVersion 19
-        targetSdkVersion 24
+        minSdkVersion 26
+        targetSdkVersion 26
         versionCode 1
         versionName "1.0"
         externalNativeBuild {
@@ -58,7 +58,7 @@
 
 
 dependencies {
-    implementation 'com.google.vr:sdk-base:1.190.0'
+    implementation 'com.google.vr:sdk-base:1.200.0'
 }
 
 build.dependsOn(':extractNdk')
diff --git a/samples/ndk-hellovrbeta/src/main/AndroidManifest.xml b/samples/ndk-hellovrbeta/src/main/AndroidManifest.xml
index 0daab74..7b90f51 100644
--- a/samples/ndk-hellovrbeta/src/main/AndroidManifest.xml
+++ b/samples/ndk-hellovrbeta/src/main/AndroidManifest.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.google.vr.ndk.samples.hellovrbeta"
-    android:versionCode="181016016"
-    android:versionName="1.190.0">
+    android:versionCode="190204066"
+    android:versionName="1.200.0">
 
   <!-- The GVR SDK Beta requires API 26+ and OpenGL ES 2+. -->
-  <uses-sdk android:minSdkVersion="26" android:targetSdkVersion="26" />
+
   <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
   <!-- Required for vibration feedback when the trigger action is performed. -->
@@ -51,6 +51,7 @@
            Daydream Home menu. -->
       <intent-filter>
           <action android:name="android.intent.action.MAIN" />
+          <category android:name="android.intent.category.LAUNCHER" />
           <category android:name="com.google.intent.category.DAYDREAM"/>
       </intent-filter>
     </activity>
diff --git a/samples/ndk-hellovrbeta/src/main/jni/controllers.cc b/samples/ndk-hellovrbeta/src/main/jni/controllers.cc
index d84216e..83ed9bd 100644
--- a/samples/ndk-hellovrbeta/src/main/jni/controllers.cc
+++ b/samples/ndk-hellovrbeta/src/main/jni/controllers.cc
@@ -43,8 +43,10 @@
 
 }  // unnamed namespace
 
-Controller::Controller(gvr::ControllerApi* gvr_controller_api, int32_t index)
+Controller::Controller(gvr::ControllerApi* gvr_controller_api, int32_t index,
+                       gvr::ControllerHandedness handedness)
     : index_(index),
+      handedness_(handedness),
       type_(GVR_BETA_CONTROLLER_CONFIGURATION_UNKNOWN),
       show_laser_(index == 0),
       is_tracking_(true),
@@ -72,22 +74,15 @@
                         float floor_offset) {
   const int old_status = state_.GetApiStatus();
   const int old_connection_state = state_.GetConnectionState();
+
+  // Apply an arm model for 3DOF controllers, 6DOF controllers will ignore this.
+  gvr_controller_api->ApplyArmModel(
+      index_, handedness_, gvr::kArmModelBehaviorFollowGazeWith6DOFPosition,
+      head_space_from_start_space_transform);
+
   // Read current controller state.
   state_.Update(*gvr_controller_api, index_);
 
-  gvr::Vec3f head_position = {};
-  // If this controller is 3DOF, apply an arm model and offset.
-  if (type_ == GVR_BETA_CONTROLLER_CONFIGURATION_3DOF) {
-    gvr_controller_api->ApplyArmModel(index_, gvr::kControllerRightHanded,
-                                      GVR_ARM_MODEL_SYNC_GAZE,
-                                      head_space_from_start_space_transform);
-    head_position =
-        PositionFromHeadSpace(head_space_from_start_space_transform);
-  } else {
-    // Incorporate the floor offset into the controller position.
-    head_position.y = -floor_offset;
-  }
-
   UpdateTrackingStatus();
 
   // Print new API status and connection state, if they changed.
@@ -99,7 +94,11 @@
         gvr_controller_connection_state_to_string(state_.GetConnectionState()));
   }
 
-  position_ = state_.GetPosition() + head_position;
+  position_ = state_.GetPosition();
+  // ApplyArmModel updates the floor offset in the 3DOF case, but not 6DOF.
+  if (type_ == GVR_BETA_CONTROLLER_CONFIGURATION_6DOF) {
+    position_.y -= floor_offset;
+  }
 
   transform_ = MatrixMul(GetTranslationMatrix(GetPosition()),
                          ControllerQuatToMatrix(GetOrientation()));
@@ -113,13 +112,30 @@
   float level = static_cast<float>(state_.GetBatteryLevel());
   battery_charge_ =
       level / static_cast<float>(GVR_CONTROLLER_BATTERY_LEVEL_FULL);
+
+  // Track any gestures made since the last update:
+  gesture_api_.Update(&state_);
+}
+
+bool Controller::GetSwipeGesture(gvr_gesture_direction* swipe_direction) const {
+  // Get the number of detected gestures
+  int num_gestures = gesture_api_.GetGestureCount();
+  for (int i = 0; i < num_gestures; ++i) {
+    const gvr::Gesture* gesture = gesture_api_.GetGesture(i);
+    if (gesture_api_.GetGestureType(gesture) == GVR_GESTURE_SWIPE) {
+      *swipe_direction = gesture_api_.GetGestureDirection(gesture);
+      return true;
+    }
+  }
+  return false;
 }
 
 Controllers::Controllers(gvr::GvrApi* gvr_api)
-    : gvr_controller_api_(new gvr::ControllerApi) {
+    : gvr_api_(gvr_api), gvr_controller_api_(new gvr::ControllerApi) {
   HELLOVRBETA_CHECK(gvr_controller_api_->Init(
-      gvr::ControllerApi::DefaultOptions() | GVR_CONTROLLER_ENABLE_ARM_MODEL,
-      gvr_api->cobj()));
+      gvr::ControllerApi::DefaultOptions() | GVR_CONTROLLER_ENABLE_ARM_MODEL |
+          GVR_CONTROLLER_ENABLE_GYRO,
+      gvr_api_->cobj()));
 }
 
 void Controllers::Initialize(JNIEnv* env, jobject java_asset_mgr,
@@ -158,17 +174,27 @@
 
 void Controllers::Resume() { gvr_controller_api_->Resume(); }
 
+void Controllers::ReconnectIfRequired() {
+  int32_t controller_count = gvr_controller_api_->GetControllerCount();
+  if (controller_count != controllers_.size()) {
+    const gvr::UserPrefs user_prefs = gvr_api_->GetUserPrefs();
+    const int32_t dominant_hand =
+        gvr_user_prefs_get_controller_handedness(user_prefs.cobj());
+    controllers_.clear();
+    for (int32_t i = 0; i < controller_count; ++i) {
+      gvr::ControllerHandedness handedness =
+          static_cast<gvr::ControllerHandedness>(i == 0 ? dominant_hand
+                                                        : !dominant_hand);
+      controllers_.push_back(
+          Controller(gvr_controller_api_.get(), i, handedness));
+    }
+  }
+}
+
 void Controllers::Update(
     const gvr::Mat4f& head_space_from_start_space_transform,
     float floor_offset) {
-  // Check to see if we've lost or gained a new controller.
-  int32_t controller_count = gvr_controller_api_->GetControllerCount();
-  if (controller_count != controllers_.size()) {
-    controllers_.clear();
-    for (int32_t i = 0; i < controller_count; ++i) {
-      controllers_.push_back(Controller(gvr_controller_api_.get(), i));
-    }
-  }
+  ReconnectIfRequired();
 
   for (auto& controller : controllers_) {
     controller.Update(gvr_controller_api_.get(),
@@ -207,6 +233,11 @@
         controller.GetState().GetButtonUp(GVR_CONTROLLER_BUTTON_TRIGGER)) {
       on_trigger_up_(controller.GetIndex());
     }
+
+    gvr_gesture_direction gesture_direction;
+    if (on_swipe_ && controller.GetSwipeGesture(&gesture_direction)) {
+      on_swipe_(controller.GetIndex(), gesture_direction);
+    }
   }
 }
 
@@ -345,4 +376,9 @@
   on_app_button_up_ = std::move(on_app_button_up);
 }
 
+void Controllers::SetOnSwipe(
+    std::function<void(int, gvr_gesture_direction)> on_swipe) {
+  on_swipe_ = std::move(on_swipe);
+}
+
 }  // namespace ndk_hello_vr_beta
diff --git a/samples/ndk-hellovrbeta/src/main/jni/controllers.h b/samples/ndk-hellovrbeta/src/main/jni/controllers.h
index fa1caa2..203194f 100644
--- a/samples/ndk-hellovrbeta/src/main/jni/controllers.h
+++ b/samples/ndk-hellovrbeta/src/main/jni/controllers.h
@@ -25,9 +25,9 @@
 
 #include "shader_program.h"  // NOLINT
 #include "util.h"  // NOLINT
-#include "vr/gvr/capi/include/gvr.h"
 #include "vr/gvr/capi/include/gvr_beta.h"
 #include "vr/gvr/capi/include/gvr_controller.h"
+#include "vr/gvr/capi/include/gvr_gesture.h"
 #include "vr/gvr/capi/include/gvr_types.h"
 
 namespace ndk_hello_vr_beta {
@@ -37,7 +37,8 @@
  */
 class Controller {
  public:
-  Controller(gvr::ControllerApi* gvr_controller_api, int32_t index);
+  Controller(gvr::ControllerApi* gvr_controller_api, int32_t index,
+             gvr::ControllerHandedness handedness);
 
   void Update(gvr::ControllerApi* gvr_controller_api_,
               const gvr::Mat4f& head_space_from_start_space_transform,
@@ -59,12 +60,16 @@
 
   float GetBatteryCharge() const { return battery_charge_; }
 
+  bool GetSwipeGesture(gvr_gesture_direction* swipe_direction) const;
+
  private:
   void UpdateTrackingStatus();
 
   int32_t index_;
+  gvr::ControllerHandedness handedness_;
   gvr_beta_controller_configuration_type type_;
   gvr::ControllerState state_;
+  gvr::GestureApi gesture_api_;
   gvr::Vec3f position_;
   gvr::Mat4f transform_;
   gvr::Mat4f laser_transform_;
@@ -105,12 +110,15 @@
   void SetOnGripUp(std::function<void(int)> on_grip);
   void SetOnAppButtonDown(std::function<void(int)> on_app_button);
   void SetOnAppButtonUp(std::function<void(int)> on_app_button);
+  void SetOnSwipe(std::function<void(int, gvr_gesture_direction)> on_swipe);
 
   Controller& GetController(int index) { return controllers_[index]; }
 
  private:
   void UpdateBatteryUniforms(const Controller& controller) const;
+  void ReconnectIfRequired();
 
+  gvr::GvrApi* gvr_api_;
   std::unique_ptr<gvr::ControllerApi> gvr_controller_api_;
 
   ControllerShaderProgram controller_shader_;
@@ -132,6 +140,7 @@
   std::function<void(int index)> on_grip_up_;
   std::function<void(int index)> on_app_button_down_;
   std::function<void(int index)> on_app_button_up_;
+  std::function<void(int index, gvr_gesture_direction direction)> on_swipe_;
 };
 
 }  // namespace ndk_hello_vr_beta
diff --git a/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.cc b/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.cc
index 9fff19b..fd17524 100644
--- a/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.cc
+++ b/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.cc
@@ -62,6 +62,9 @@
       gvr_audio_api_(std::move(gvr_audio_api)),
       viewports_{gvr_api_->CreateBufferViewport(),
                  gvr_api_->CreateBufferViewport()},
+      see_through_config_(gvr_beta_see_through_config_create(gvr_context)),
+      see_through_mode_(SHOW_SEE_THROUGH),
+      see_through_effect_(GVR_BETA_SEE_THROUGH_CAMERA_MODE_RAW_IMAGE),
       controllers_(gvr_api_.get()),
       controller_on_target_index_(-1),
       target_held_(false),
@@ -83,6 +86,10 @@
       [this](int controller_index) { OnGrabTarget(controller_index); });
   controllers_.SetOnGripUp(
       [this](int controller_index) { OnReleaseTarget(controller_index); });
+  controllers_.SetOnSwipe(
+      [this](int controller_index, gvr_gesture_direction direction) {
+        OnSwipe(controller_index, direction);
+      });
 }
 
 HelloVrBetaApp::~HelloVrBetaApp() {
@@ -97,19 +104,25 @@
 
   HELLOVRBETA_CHECK(gvr_api_->IsFeatureSupported(GVR_FEATURE_MULTIVIEW));
 
+  // Initialize the see-through settings.
+  UpdateSeeThroughSettings();
+
   shader_.Link();
+  alpha_shader_.Link();
 
   CheckGLError("Obj program");
 
   GLuint position_param = shader_.GetPositionAttribute();
   GLuint uv_param = shader_.GetUVAttribute();
+  GLuint alpha_position_param = alpha_shader_.GetPositionAttribute();
+  GLuint alpha_uv_param = alpha_shader_.GetUVAttribute();
 
   CheckGLError("Obj program params");
 
   controllers_.Initialize(env, java_asset_mgr_, asset_mgr_);
 
-  HELLOVRBETA_CHECK(
-      room_.Initialize(asset_mgr_, "CubeRoom.obj", position_param, uv_param));
+  HELLOVRBETA_CHECK(room_.Initialize(asset_mgr_, "CubeRoom.obj",
+                                     alpha_position_param, alpha_uv_param));
   HELLOVRBETA_CHECK(room_texture_.Initialize(env, java_asset_mgr_,
                                              "CubeRoom_BakedDiffuse.png"));
   HELLOVRBETA_CHECK(target_object_mesh_.Initialize(asset_mgr_, "TriSphere.obj",
@@ -134,7 +147,7 @@
   specs[0].SetSamples(2);
 
   // With multiview, the distortion buffer is a texture array with two layers
-  // whose width is half the display width.
+  // whose width is half the offscreen render width.
   gvr::Sizei half_size = {render_size_.width / 2, render_size_.height};
   specs[0].SetMultiviewLayers(2);
   specs[0].SetSize(half_size);
@@ -244,6 +257,34 @@
   }
 }
 
+void HelloVrBetaApp::OnSwipe(int controller_index,
+                             gvr_gesture_direction direction) {
+  switch (direction) {
+    case GVR_GESTURE_DIRECTION_LEFT:
+      --see_through_mode_;
+      // If see_through_mode_ is too low, loop back to the last mode.
+      if (see_through_mode_ < SHOW_SEE_THROUGH) {
+        see_through_mode_ = NO_SEE_THROUGH;
+      }
+      break;
+    case GVR_GESTURE_DIRECTION_RIGHT:
+      ++see_through_mode_;
+      // If see_through_mode_ is too high, loop back to the first mode.
+      if (see_through_mode_ > NO_SEE_THROUGH) {
+        see_through_mode_ = SHOW_SEE_THROUGH;
+      }
+      break;
+    case GVR_GESTURE_DIRECTION_DOWN:
+    case GVR_GESTURE_DIRECTION_UP:
+      see_through_effect_ =
+          (see_through_effect_ == GVR_BETA_SEE_THROUGH_CAMERA_MODE_RAW_IMAGE)
+              ? GVR_BETA_SEE_THROUGH_CAMERA_MODE_TONEMAPPED
+              : GVR_BETA_SEE_THROUGH_CAMERA_MODE_RAW_IMAGE;
+      break;
+  }
+  UpdateSeeThroughSettings();
+}
+
 void HelloVrBetaApp::OnPause() {
   gvr_api_->PauseTracking();
   gvr_audio_api_->Pause();
@@ -257,14 +298,71 @@
   controllers_.Resume();
 }
 
+bool HelloVrBetaApp::IsSeeThroughAvailable() const {
+  const int32_t see_through_feature = GVR_BETA_FEATURE_SEE_THROUGH;
+  if (!gvr_api_->IsFeatureSupported(see_through_feature)) {
+    return false;
+  }
+
+  if (gvr_api_->GetUserPrefs().IsFeatureEnabled(see_through_feature)) {
+    return true;
+  }
+
+  // Ask the user to turn on see-through. This is does not block.
+  gvr_api_->RequestFeatures(/*required_features=*/nullptr,
+                            /*required_count=*/0, &see_through_feature,
+                            /*optional_count=*/1,
+                            /*on_complete_activity=*/nullptr);
+
+  // Even if see-through is enabled through the feature request, see-through is
+  // still not available since turning on see-through requires a reboot.
+  return false;
+}
+
+void HelloVrBetaApp::UpdateSeeThroughSettings() {
+  // If trying to show pass through, but it is not available, return.
+  if (!IsSeeThroughAvailable()) {
+    see_through_mode_ = NO_SEE_THROUGH;
+    return;
+  }
+
+  // We have 3 see-through modes, if the modes are SHOW_SEE_THROUGH or
+  // SHOW_TRANSLUCENT_SEE_THROUGH, we need to set turn on see-through in gvr.
+  // When we use SHOW_TRANSLUCENT_SEE_THROUGH, the room will be rendered
+  // translucently. If see-through is enabled, see_through_effect_
+  // determines if we use the raw camera image, or if we render the tone mapped
+  // camera image.
+  int camera_mode = GVR_BETA_SEE_THROUGH_CAMERA_MODE_DISABLED;
+  int scene_type = GVR_BETA_SEE_THROUGH_SCENE_TYPE_VIRTUAL_SCENE;
+
+  switch (see_through_mode_) {
+    case SHOW_SEE_THROUGH:
+    case SHOW_TRANSLUCENT_SEE_THROUGH:
+      camera_mode = see_through_effect_;
+      // If see-through is on, we also set the scene type to augmented scene.
+      // This will alter the head pose to match the see-through's camera
+      // position which could be offset from the eye.
+      scene_type = GVR_BETA_SEE_THROUGH_SCENE_TYPE_AUGMENTED_SCENE;
+      break;
+    case NO_SEE_THROUGH:
+      break;
+  }
+  gvr_beta_see_through_config_set_camera_mode(see_through_config_, camera_mode);
+  gvr_beta_see_through_config_set_scene_type(see_through_config_, scene_type);
+  gvr_beta_set_see_through_config(context_, see_through_config_);
+}
+
 /**
  * Draws a frame for a particular view.
  */
 void HelloVrBetaApp::DrawWorld(const gvr::Mat4f view[2],
                                const gvr::Mat4f view_projection[2]) {
   glViewport(0, 0, render_size_.width / 2, render_size_.height);
+  if (see_through_mode_ != SHOW_SEE_THROUGH) {
+    DrawRoom(view_projection);
+  }
+
   DrawTarget(view_projection);
-  DrawRoom(view_projection);
   controllers_.Draw(view, view_projection);
 }
 
@@ -296,8 +394,10 @@
 void HelloVrBetaApp::DrawRoom(const gvr::Mat4f view_projection[2]) {
   gvr::Mat4f model_room = GetTranslationMatrix({0.0f, 0.0f, 0.0f});
 
-  shader_.Use();
-  shader_.SetModelViewProjection(model_room, view_projection);
+  alpha_shader_.Use();
+  alpha_shader_.SetModelViewProjection(model_room, view_projection);
+  float alpha = see_through_mode_ == SHOW_TRANSLUCENT_SEE_THROUGH ? 0.7f : 1.0f;
+  alpha_shader_.SetAlpha(alpha);
 
   room_texture_.Bind();
   room_.Draw();
diff --git a/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.h b/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.h
index d1ddf71..40c96d4 100644
--- a/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.h
+++ b/samples/ndk-hellovrbeta/src/main/jni/hello_vr_beta_app.h
@@ -131,6 +131,14 @@
    */
   void OnReleaseTarget(int controller_index);
 
+  /**
+   * Controller touchpad is swiped.
+   */
+  void OnSwipe(int controller_index, gvr_gesture_direction direction);
+
+  bool IsSeeThroughAvailable() const;
+  void UpdateSeeThroughSettings();
+
   void SetTargetPosition(const gvr::Vec3f& position);
   float GetFloorOffset();
 
@@ -141,8 +149,17 @@
   std::unique_ptr<gvr::BufferViewportList> viewport_list_;
   std::array<gvr::BufferViewport, 2> viewports_;
   std::unique_ptr<gvr::SwapChain> swapchain_;
-  Controllers controllers_;
 
+  gvr_beta_see_through_config* see_through_config_;
+  enum SeeThroughMode {
+    SHOW_SEE_THROUGH,              // Do not render room.
+    SHOW_TRANSLUCENT_SEE_THROUGH,  // Render room translucently.
+    NO_SEE_THROUGH                 // Turn off see-through and render room.
+  };
+  int see_through_mode_;
+  int see_through_effect_;
+
+  Controllers controllers_;
   int controller_on_target_index_;
   bool target_held_;
 
@@ -153,6 +170,7 @@
   Texture target_object_selected_texture_;
 
   TexturedShaderProgram shader_;
+  TexturedAlphaShaderProgram alpha_shader_;
 
   gvr::Mat4f model_target_;
   gvr::Sizei render_size_;
diff --git a/samples/ndk-hellovrbeta/src/main/jni/shader_program.cc b/samples/ndk-hellovrbeta/src/main/jni/shader_program.cc
index 122b484..d23ed56 100644
--- a/samples/ndk-hellovrbeta/src/main/jni/shader_program.cc
+++ b/samples/ndk-hellovrbeta/src/main/jni/shader_program.cc
@@ -56,6 +56,22 @@
       FragColor = texture(u_Texture, vec2(v_UV.x, 1.0 - v_UV.y));
     })glsl";
 
+constexpr const char* kTexturedAlphaMeshFragmentShader =
+    R"glsl(#version 320 es
+
+    precision mediump float;
+    in vec2 v_UV;
+    out vec4 FragColor;
+    uniform sampler2D u_Texture;
+    uniform float a_Alpha;
+
+    void main() {
+      // The y coordinate of this sample's textures is reversed compared to
+      // what OpenGL expects, so we invert the y coordinate.
+      FragColor = texture(u_Texture, vec2(v_UV.x, 1.0 - v_UV.y));
+      FragColor.a = FragColor.a * a_Alpha;
+    })glsl";
+
 constexpr const char* kTexturedMeshAlphaFragmentShader =
     R"glsl(#version 320 es
 
@@ -155,6 +171,17 @@
   return glGetAttribLocation(program_, "a_UV");
 }
 
+void TexturedAlphaShaderProgram::Link() {
+  ShaderProgram::Link(kTexturedMeshVertexShader,
+                      kTexturedAlphaMeshFragmentShader);
+  mode_view_projection_ = glGetUniformLocation(program_, "u_MVP");
+  alpha_ = glGetUniformLocation(program_, "a_Alpha");
+}
+
+void TexturedAlphaShaderProgram::SetAlpha(float alpha) const {
+  glUniform1f(alpha_, alpha);
+}
+
 void ControllerShaderProgram::Link() {
   ShaderProgram::Link(kTexturedMeshVertexShader,
                       kTexturedMeshAlphaFragmentShader);
@@ -165,10 +192,6 @@
   SetAlpha(1.0f);
 }
 
-void ControllerShaderProgram::SetAlpha(float alpha) const {
-  glUniform1f(alpha_, alpha);
-}
-
 void ControllerShaderProgram::SetBatteryUVRect(const gvr::Rectf& uv) const {
   glUniform4f(battery_uv_rect_, uv.left, uv.bottom, uv.right, uv.top);
 }
diff --git a/samples/ndk-hellovrbeta/src/main/jni/shader_program.h b/samples/ndk-hellovrbeta/src/main/jni/shader_program.h
index 1ad0d2e..90ca571 100644
--- a/samples/ndk-hellovrbeta/src/main/jni/shader_program.h
+++ b/samples/ndk-hellovrbeta/src/main/jni/shader_program.h
@@ -50,16 +50,24 @@
   GLuint mode_view_projection_;
 };
 
-class ControllerShaderProgram : public TexturedShaderProgram {
+class TexturedAlphaShaderProgram : public TexturedShaderProgram {
  public:
   void Link();
 
   void SetAlpha(float alpha) const;
+
+ protected:
+  GLuint alpha_;
+};
+
+class ControllerShaderProgram : public TexturedAlphaShaderProgram {
+ public:
+  void Link();
+
   void SetBatteryUVRect(const gvr::Rectf& uv) const;
   void SetBatteryOffset(const gvr::Vec2f& offset) const;
 
  protected:
-  GLuint alpha_;
   GLuint battery_uv_rect_;
   GLuint battery_offset_;
 };
diff --git a/samples/sdk-controllerclient/build.gradle b/samples/sdk-controllerclient/build.gradle
index 7389303..1fa10ca 100644
--- a/samples/sdk-controllerclient/build.gradle
+++ b/samples/sdk-controllerclient/build.gradle
@@ -20,7 +20,7 @@
 
     defaultConfig {
         minSdkVersion 24
-        targetSdkVersion 24
+        targetSdkVersion 26
         versionCode 1
         versionName "1.0"
     }
@@ -35,5 +35,5 @@
 }
 
 dependencies {
-    implementation 'com.google.vr:sdk-base:1.190.0'
+    implementation 'com.google.vr:sdk-base:1.200.0'
 }
diff --git a/samples/sdk-controllerclient/src/main/AndroidManifest.xml b/samples/sdk-controllerclient/src/main/AndroidManifest.xml
index c4ddc03..3a3b381 100644
--- a/samples/sdk-controllerclient/src/main/AndroidManifest.xml
+++ b/samples/sdk-controllerclient/src/main/AndroidManifest.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.google.vr.sdk.samples.controllerclient"
-  android:versionCode="181016016"
-  android:versionName="1.190.0">
-  <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="24" />
+  android:versionCode="190204066"
+  android:versionName="1.200.0">
+
   <uses-feature android:glEsVersion="0x00030002" android:required="true" />
 
   <application
diff --git a/samples/sdk-hellovr/build.gradle b/samples/sdk-hellovr/build.gradle
index dfb7853..9f5e99d 100644
--- a/samples/sdk-hellovr/build.gradle
+++ b/samples/sdk-hellovr/build.gradle
@@ -20,7 +20,7 @@
 
     defaultConfig {
         minSdkVersion 19
-        targetSdkVersion 24
+        targetSdkVersion 26
         versionCode 1
         versionName "1.0"
     }
@@ -35,7 +35,7 @@
 }
 
 dependencies {
-    implementation 'com.google.vr:sdk-base:1.190.0'
+    implementation 'com.google.vr:sdk-base:1.200.0'
 
     // Obj - a simple Wavefront OBJ file loader
     // https://github.com/javagl/Obj
diff --git a/samples/sdk-hellovr/src/main/AndroidManifest.xml b/samples/sdk-hellovr/src/main/AndroidManifest.xml
index 64e71e6..f17ab4d 100644
--- a/samples/sdk-hellovr/src/main/AndroidManifest.xml
+++ b/samples/sdk-hellovr/src/main/AndroidManifest.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.google.vr.sdk.samples.hellovr"
-      android:versionCode="181016016"
-      android:versionName="1.190.0">
+      android:versionCode="190204066"
+      android:versionName="1.200.0">
 
     <!-- The GVR SDK requires API 19+ and OpenGL ES 2+. -->
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24" />
+
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
     <!-- Required for vibration feedback when the trigger action is performed. -->
diff --git a/samples/sdk-hellovr/src/main/java/com/google/vr/sdk/samples/hellovr/HelloVrActivity.java b/samples/sdk-hellovr/src/main/java/com/google/vr/sdk/samples/hellovr/HelloVrActivity.java
index af1549d..48c85ab 100644
--- a/samples/sdk-hellovr/src/main/java/com/google/vr/sdk/samples/hellovr/HelloVrActivity.java
+++ b/samples/sdk-hellovr/src/main/java/com/google/vr/sdk/samples/hellovr/HelloVrActivity.java
@@ -20,6 +20,9 @@
 import android.opengl.Matrix;
 import android.os.Bundle;
 import android.util.Log;
+import com.google.vr.ndk.base.Properties;
+import com.google.vr.ndk.base.Properties.PropertyType;
+import com.google.vr.ndk.base.Value;
 import com.google.vr.sdk.audio.GvrAudioEngine;
 import com.google.vr.sdk.base.AndroidCompat;
 import com.google.vr.sdk.base.Eye;
@@ -59,7 +62,7 @@
   private static final String OBJECT_SOUND_FILE = "audio/HelloVR_Loop.ogg";
   private static final String SUCCESS_SOUND_FILE = "audio/HelloVR_Activation.ogg";
 
-  private static final float FLOOR_HEIGHT = -2.0f;
+  private static final float DEFAULT_FLOOR_HEIGHT = -1.6f;
 
   private static final float ANGLE_LIMIT = 0.2f;
 
@@ -127,6 +130,11 @@
   private volatile int sourceId = GvrAudioEngine.INVALID_ID;
   private volatile int successSourceId = GvrAudioEngine.INVALID_ID;
 
+  private Properties gvrProperties;
+  // This is an opaque wrapper around an internal GVR property. It is set via Properties and
+  // should be shutdown via a {@link Value#close()} call when no longer needed.
+  private final Value floorHeight = new Value();
+
   /**
    * Sets the view to our GvrView and initializes the transformation matrices we will use
    * to render our scene.
@@ -176,6 +184,7 @@
     }
 
     setGvrView(gvrView);
+    gvrProperties = gvrView.getGvrApi().getCurrentProperties();
   }
 
   @Override
@@ -193,6 +202,7 @@
   @Override
   public void onRendererShutdown() {
     Log.i(TAG, "onRendererShutdown");
+    floorHeight.close();
   }
 
   @Override
@@ -222,7 +232,7 @@
     Util.checkGlError("Object program params");
 
     Matrix.setIdentityM(modelRoom, 0);
-    Matrix.translateM(modelRoom, 0, 0, FLOOR_HEIGHT, 0);
+    Matrix.translateM(modelRoom, 0, 0, DEFAULT_FLOOR_HEIGHT, 0);
 
     // Avoid any delays during start-up due to decoding of sound files.
     new Thread(
@@ -295,6 +305,12 @@
     // Build the camera matrix and apply it to the ModelView.
     Matrix.setLookAtM(camera, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
 
+    if (gvrProperties.get(PropertyType.TRACKING_FLOOR_HEIGHT, floorHeight)) {
+      // The floor height can change each frame when tracking system detects a new floor position.
+      Matrix.setIdentityM(modelRoom, 0);
+      Matrix.translateM(modelRoom, 0, 0, floorHeight.asFloat(), 0);
+    } // else the device doesn't support floor height detection so DEFAULT_FLOOR_HEIGHT is used.
+
     headTransform.getHeadView(headView, 0);
 
     // Update the 3d audio engine with the most recent head rotation.
diff --git a/samples/sdk-video360/build.gradle b/samples/sdk-video360/build.gradle
index 1e1ddd9..0617b5c 100644
--- a/samples/sdk-video360/build.gradle
+++ b/samples/sdk-video360/build.gradle
@@ -20,7 +20,7 @@
 
     defaultConfig {
         minSdkVersion 24
-        targetSdkVersion 24
+        targetSdkVersion 26
         versionCode 1
         versionName "1.0"
     }
@@ -36,5 +36,5 @@
 
 dependencies {
     implementation 'com.android.support:appcompat-v7:26.1.0'
-    implementation 'com.google.vr:sdk-base:1.190.0'
+    implementation 'com.google.vr:sdk-base:1.200.0'
 }
diff --git a/samples/sdk-video360/src/main/AndroidManifest.xml b/samples/sdk-video360/src/main/AndroidManifest.xml
index 78cdf81..971d836 100644
--- a/samples/sdk-video360/src/main/AndroidManifest.xml
+++ b/samples/sdk-video360/src/main/AndroidManifest.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.google.vr.sdk.samples.video360"
-    android:versionCode="181016016"
-    android:versionName="1.190.0">
+    android:versionCode="190204066"
+    android:versionName="1.200.0">
 
   <!-- The VR app is Daydream-only since it uses the controller. -->
-  <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="24"/>
+
   <uses-feature android:glEsVersion="0x00030002" android:required="true" />
 
   <uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true"/>
diff --git a/samples/sdk-videoplayer/build.gradle b/samples/sdk-videoplayer/build.gradle
index 7395ceb..af29964 100644
--- a/samples/sdk-videoplayer/build.gradle
+++ b/samples/sdk-videoplayer/build.gradle
@@ -18,9 +18,14 @@
 android {
     compileSdkVersion 26
 
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
     defaultConfig {
         minSdkVersion 24
-        targetSdkVersion 24
+        targetSdkVersion 26
         versionCode 1
         versionName "1.0"
     }
@@ -35,9 +40,9 @@
 }
 
 dependencies {
-    implementation 'com.google.android.exoplayer:exoplayer:2.6.1'
-    implementation 'com.google.android.exoplayer:extension-gvr:2.6.1'
+    implementation 'com.google.android.exoplayer:exoplayer:2.9.0'
+    implementation 'com.google.android.exoplayer:extension-gvr:2.9.0'
 
-    implementation 'com.google.vr:sdk-audio:1.190.0'
-    implementation 'com.google.vr:sdk-base:1.190.0'
+    implementation 'com.google.vr:sdk-audio:1.200.0'
+    implementation 'com.google.vr:sdk-base:1.200.0'
 }
diff --git a/samples/sdk-videoplayer/src/main/AndroidManifest.xml b/samples/sdk-videoplayer/src/main/AndroidManifest.xml
index 713d7ca..dbbcff7 100644
--- a/samples/sdk-videoplayer/src/main/AndroidManifest.xml
+++ b/samples/sdk-videoplayer/src/main/AndroidManifest.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.google.vr.sdk.samples.videoplayer"
-    android:versionCode="181016016"
-    android:versionName="1.190.0">
+    android:versionCode="190204066"
+    android:versionName="1.200.0">
 
     <!-- The video API works on Daydream-ready devices with Asynchronous
          Reprojection on Android N+ and OpenGL ES 3+ -->
-    <uses-sdk android:minSdkVersion="24" android:targetSdkVersion="24" />
+
     <uses-feature android:glEsVersion="0x00030002" android:required="true" />
 
     <!-- Required by the app to stream video. -->
diff --git a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/GLUtil.java b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/GLUtil.java
index facef25..910bfb4 100644
--- a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/GLUtil.java
+++ b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/GLUtil.java
@@ -21,12 +21,9 @@
 import android.opengl.GLES20;
 import android.opengl.GLUtils;
 import android.util.Log;
-
 import java.io.IOException;
 import java.io.InputStream;
 
-import javax.microedition.khronos.egl.EGL10;
-
 /**
  * Utility class for working with GL.
  */
@@ -41,39 +38,19 @@
    * @param tag The tag to use when logging.
    * @param op The name of the GL function called before calling checkGlError
    */
-
   public static void checkGlError(String tag, String op) {
+    int lastError = GLES20.GL_NO_ERROR;
     int error;
     while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
       Log.e(tag, op + ": glError " + error);
-      throw new RuntimeException(op + ": glError " + error);
+      lastError = error;
     }
-  }
-
-  /**
-   * Checks EGL state for errors and log a message when an error is encountered. Should be
-   * called regularly after calls to EGL functions to help with debugging.
-   *
-   * @param egl An EGL object.
-   * @param tag The tag to use when logging.
-   * @param op The name of the EGL function called before calling checkGlError
-   */
-   public static void checkEGLError(EGL10 egl, String tag, String op) {
-    int error;
-    while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
-      Log.e(tag, op + ": eglError " + error);
+    if (lastError != GLES20.GL_NO_ERROR) {
+      throw new RuntimeException(op + ": glError " + lastError);
     }
   }
 
   /**
-   * Clears all GL errors.
-   */
-  public static void clearGLErrors() {
-    int error;
-    while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {}
-  }
-
-  /**
    * Creates a texture from an Android resource.
    *
    * @param context An Application context.
diff --git a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/Settings.java b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/Settings.java
index 8028e28..ebdf9cf 100644
--- a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/Settings.java
+++ b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/Settings.java
@@ -20,6 +20,7 @@
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.util.Log;
+import java.util.Locale;
 
 /**
  * Stores settings which are settable through intent extras and persisted in a
@@ -79,13 +80,17 @@
     pref.putBoolean(USE_DRM_VIDEO_SAMPLE, useDrmVideoSample)
         .putBoolean(SHOW_FRAME_RATE_BAR, showFrameRateBar)
         .putInt(VIDEO_LENGTH_SECONDS, videoLengthSeconds)
-        .commit();
+        .apply();
   }
 
   public void dump() {
-    String settings = String.format(
-        "Use DRM video [%b], Show framerate bar [%b], Playback duration (seconds) [%d]",
-        useDrmVideoSample, showFrameRateBar, videoLengthSeconds);
+    String settings =
+        String.format(
+            Locale.US,
+            "Use DRM video [%b], Show framerate bar [%b], Playback duration (seconds) [%d]",
+            useDrmVideoSample,
+            showFrameRateBar,
+            videoLengthSeconds);
     Log.d(TAG, "Video settings: " + settings);
   }
 }
diff --git a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoExoPlayer2.java b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoExoPlayer2.java
index 4e2622c..6a90d8b 100644
--- a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoExoPlayer2.java
+++ b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoExoPlayer2.java
@@ -21,42 +21,29 @@
 import android.view.Surface;
 import com.google.android.exoplayer2.C;
 import com.google.android.exoplayer2.DefaultRenderersFactory;
-import com.google.android.exoplayer2.ExoPlaybackException;
 import com.google.android.exoplayer2.ExoPlayerFactory;
-import com.google.android.exoplayer2.PlaybackParameters;
 import com.google.android.exoplayer2.Player;
 import com.google.android.exoplayer2.SimpleExoPlayer;
-import com.google.android.exoplayer2.Timeline;
 import com.google.android.exoplayer2.audio.AudioProcessor;
 import com.google.android.exoplayer2.decoder.DecoderCounters;
 import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
 import com.google.android.exoplayer2.drm.DrmSessionManager;
+import com.google.android.exoplayer2.drm.ExoMediaDrm;
 import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
 import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
 import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
 import com.google.android.exoplayer2.drm.UnsupportedDrmException;
 import com.google.android.exoplayer2.ext.gvr.GvrAudioProcessor;
-import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
 import com.google.android.exoplayer2.source.ClippingMediaSource;
 import com.google.android.exoplayer2.source.ExtractorMediaSource;
 import com.google.android.exoplayer2.source.MediaSource;
-import com.google.android.exoplayer2.source.TrackGroupArray;
 import com.google.android.exoplayer2.source.dash.DashMediaSource;
-import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
 import com.google.android.exoplayer2.source.hls.HlsMediaSource;
-import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
 import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
-import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
 import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
-import com.google.android.exoplayer2.trackselection.TrackSelection;
-import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
-import com.google.android.exoplayer2.upstream.DataSource;
-import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
 import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
 import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
-import com.google.android.exoplayer2.upstream.HttpDataSource;
 import com.google.android.exoplayer2.util.Util;
-import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -67,20 +54,21 @@
 public class VideoExoPlayer2 implements Player.EventListener {
 
   private static final String TAG = VideoExoPlayer2.class.getSimpleName();
-  private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
 
   private final Context context;
   private final Settings settings;
-  private final String userAgent;
-  private final DataSource.Factory mediaDataSourceFactory;
+  private final DefaultHttpDataSourceFactory httpDataSourceFactory;
+  private final DefaultDataSourceFactory mediaDataSourceFactory;
   private GvrAudioProcessor gvrAudioProcessor;
   private SimpleExoPlayer player;
+  private ExoMediaDrm<FrameworkMediaCrypto> mediaDrm;
 
   public VideoExoPlayer2(Context context, Settings settings) {
     this.context = context;
     this.settings = settings;
-    userAgent = Util.getUserAgent(context, "VideoExoPlayer");
-    mediaDataSourceFactory = buildDataSourceFactory(true);
+    String userAgent = Util.getUserAgent(context, "VideoExoPlayer");
+    httpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
+    mediaDataSourceFactory = new DefaultDataSourceFactory(context, httpDataSourceFactory);
   }
 
   public void play() {
@@ -147,10 +135,7 @@
     DrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
     if (optionalDrmVideoId != null) {
       try {
-        drmSessionManager =
-            buildDrmSessionManager(
-                C.WIDEVINE_UUID,
-                getWidevineTestLicenseUrl(optionalDrmVideoId));
+        mediaDrm = FrameworkMediaDrm.newInstance(C.WIDEVINE_UUID);
       } catch (UnsupportedDrmException e) {
         String errorString =
             e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
@@ -159,16 +144,21 @@
         Log.e(TAG, "Error: " + errorString, e);
         throw e;
       }
+      String licenseUrl = getWidevineTestLicenseUrl(optionalDrmVideoId);
+      HttpMediaDrmCallback drmCallback =
+          new HttpMediaDrmCallback(licenseUrl, httpDataSourceFactory);
+      drmSessionManager =
+          new DefaultDrmSessionManager<>(
+              C.WIDEVINE_UUID, mediaDrm, drmCallback, /* optionalKeyRequestParameters= */ null);
     }
 
-    TrackSelection.Factory videoTrackSelectionFactory =
-        new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
-    DefaultTrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
-
     gvrAudioProcessor = new GvrAudioProcessor();
-    player = ExoPlayerFactory.newSimpleInstance(
-        new GvrRenderersFactory(context, drmSessionManager, gvrAudioProcessor),
-        trackSelector);
+    player =
+        ExoPlayerFactory.newSimpleInstance(
+            context,
+            new GvrRenderersFactory(context, gvrAudioProcessor),
+            new DefaultTrackSelector(),
+            drmSessionManager);
     player.addListener(this);
 
     // Auto play the video.
@@ -177,7 +167,14 @@
     MediaSource mediaSource = buildMediaSource(uri);
     if (settings.videoLengthSeconds > 0) {
       long lengthMicroseconds = TimeUnit.SECONDS.toMicros(settings.videoLengthSeconds);
-      mediaSource = new ClippingMediaSource(mediaSource, 0, lengthMicroseconds, false);
+      mediaSource =
+          new ClippingMediaSource(
+              mediaSource,
+              /* startPositionUs= */ 0,
+              lengthMicroseconds,
+              /* enableInitialDiscontinuity= */ false,
+              /* allowDynamicClippingUpdates= */ false,
+              /* relativeToDefaultPosition= */ false);
     }
     // Prepare the player with the source.
     player.prepare(mediaSource);
@@ -194,6 +191,10 @@
       player.release();
       player = null;
       gvrAudioProcessor = null;
+      if (mediaDrm != null) {
+        mediaDrm.release();
+        mediaDrm = null;
+      }
     }
   }
 
@@ -201,74 +202,19 @@
     return "https://proxy.uat.widevine.com/proxy?video_id=" + id + "&provider=widevine_test";
   }
 
-  /**
-   * Returns a new DataSource factory.
-   *
-   * @param useBandwidthMeter Whether to set {@link #BANDWIDTH_METER} as a listener to the new
-   *     DataSource factory.
-   * @return A new DataSource factory.
-   */
-  private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) {
-    return buildDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
-  }
-
-  private DataSource.Factory buildDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
-    return new DefaultDataSourceFactory(
-        context, bandwidthMeter, buildHttpDataSourceFactory(bandwidthMeter));
-  }
-
-  /**
-   * Returns a new HttpDataSource factory.
-   *
-   * @param useBandwidthMeter Whether to set {@link #BANDWIDTH_METER} as a listener to the new
-   *     DataSource factory.
-   * @return A new HttpDataSource factory.
-   */
-  private HttpDataSource.Factory buildHttpDataSourceFactory(boolean useBandwidthMeter) {
-    return buildHttpDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
-  }
-
-  private HttpDataSource.Factory buildHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
-    return new DefaultHttpDataSourceFactory(userAgent, bandwidthMeter);
-  }
-
-  private DrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManager(
-      UUID uuid, String licenseUrl) throws UnsupportedDrmException {
-    if (Util.SDK_INT < 18) {
-      return null;
-    }
-    HttpMediaDrmCallback drmCallback =
-        new HttpMediaDrmCallback(licenseUrl, buildHttpDataSourceFactory(false));
-    return new DefaultDrmSessionManager<>(
-        uuid, FrameworkMediaDrm.newInstance(uuid), drmCallback, null, null, null);
-  }
-
   private MediaSource buildMediaSource(Uri uri) {
     int type = Util.inferContentType(uri.getLastPathSegment());
     switch (type) {
       case C.TYPE_SS:
-        return new SsMediaSource(
-            uri,
-            buildDataSourceFactory(false),
-            new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
-            null,
-            null);
+        return new SsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
       case C.TYPE_DASH:
-        return new DashMediaSource(
-            uri,
-            buildDataSourceFactory(false),
-            new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
-            null,
-            null);
+        return new DashMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
       case C.TYPE_HLS:
-        return new HlsMediaSource(uri, mediaDataSourceFactory, null, null);
+        return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
       case C.TYPE_OTHER:
-        return new ExtractorMediaSource(
-            uri, mediaDataSourceFactory, new DefaultExtractorsFactory(), null, null);
+        return new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
       default:
-        {
-          throw new IllegalStateException("Unsupported type: " + type);
-        }
+        throw new IllegalStateException("Unsupported type: " + type);
     }
   }
 
@@ -276,10 +222,8 @@
 
     private final GvrAudioProcessor gvrAudioProcessor;
 
-    private GvrRenderersFactory(Context context,
-        DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
-        GvrAudioProcessor gvrAudioProcessor) {
-      super(context, drmSessionManager);
+    private GvrRenderersFactory(Context context, GvrAudioProcessor gvrAudioProcessor) {
+      super(context);
       this.gvrAudioProcessor = gvrAudioProcessor;
     }
 
@@ -304,30 +248,4 @@
     return counters.renderedOutputBufferCount;
   }
 
-  @Override
-  public void onLoadingChanged(boolean isLoading) {}
-  @Override
-  public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}
-  @Override
-  public void onPlayerError(ExoPlaybackException error) {}
-
-  @Override
-  public void onPositionDiscontinuity(int reason) {}
-
-  @Override
-  public void onRepeatModeChanged(int repeatMode) {}
-
-  @Override
-  public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {}
-
-  // Old API.
-  public void onTimelineChanged(Timeline timeline, Object manifest) {}
-  // New API.
-  public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {}
-
-  @Override
-  public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {}
-
-  @Override
-  public void onSeekProcessed() {}
 }
diff --git a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoScene.java b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoScene.java
index 328141d..1d7581e 100644
--- a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoScene.java
+++ b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/VideoScene.java
@@ -226,7 +226,7 @@
    * seconds, based on the passed DecoderCounters object.
    *
    * @param averagingPeriodInSeconds Compute the average over this many seconds in the past.
-   * @param frameRate Native frame rate of the video.
+   * @param nativeFrameRate Native frame rate of the video.
    * @param counters DecoderCounters object retrieved from the video decoder.
    */
   public void updateVideoFpsFraction(
@@ -244,18 +244,18 @@
     int pastBufferCount = 0;
 
     // Insert the current buffer count into the map for future computations.
-    frameCounts.put(Long.valueOf(nowTime), Integer.valueOf(currentBufferCount));
+    frameCounts.put(nowTime, currentBufferCount);
 
     // Loop over the map, pruning outdated entries and stopping at the first one that is within the
     // cutoff time.
     for (Iterator<Map.Entry<Long, Integer>> iterator = frameCounts.entrySet().iterator();
         iterator.hasNext(); ) {
       Map.Entry<Long, Integer> count = iterator.next();
-      if (count.getKey().longValue() < cutoffTime) {
+      if (count.getKey() < cutoffTime) {
         iterator.remove();
       } else {
-        pastTime = count.getKey().longValue();
-        pastBufferCount = count.getValue().intValue();
+        pastTime = count.getKey();
+        pastBufferCount = count.getValue();
         break;
       }
     }
diff --git a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/WatchVideoActivity.java b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/WatchVideoActivity.java
index 714fc08..e5970f0 100644
--- a/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/WatchVideoActivity.java
+++ b/samples/sdk-videoplayer/src/main/java/com/google/vr/sdk/samples/videoplayer/WatchVideoActivity.java
@@ -29,6 +29,7 @@
 import com.google.android.exoplayer2.Format;
 import com.google.android.exoplayer2.drm.UnsupportedDrmException;
 import com.google.vr.ndk.base.AndroidCompat;
+import com.google.vr.ndk.base.BufferViewport;
 import com.google.vr.ndk.base.GvrLayout;
 import com.google.vr.ndk.base.GvrLayout.ExternalSurfaceListener;
 
@@ -37,7 +38,7 @@
  * detailed description of the API, see the <a
  * href="https://developers.google.com/vr/reference/gvr-ndk-rendering#using_video_viewports">ndk
  * walkthrough</a>. This sample supports DRM and unprotected video playback, configured in {@link
- * Configuration}.
+ * Settings}.
  *
  * <p>The Surface for video output is acquired from the {@link ExternalSurfaceListener} and set on
  * the video player. For each frame, this sample draws a window (alpha 0) in the scene where video
diff --git a/settings.gradle b/settings.gradle
index 355f446..e0c32d4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -14,23 +14,3 @@
 // Android Studio.
 //include ':samples:ndk-hellovr'
 //include ':samples:ndk-hellovrbeta'
-
-// Android Studio doesn't preserve nested modules in its Project View. To create
-// a cleaner layout, we reorganize and rename the modules loaded above.
-Set moduleList = new HashSet()  // Modules to display in the Project View.
-
-// Move all the modules from root/samples/simplepanowidget to
-// root/samples-simplepanowidget.
-rootProject.children.each { outerDir ->
-    outerDir.children.each { innerDir ->
-        // Rename the modules as we move them around.
-        innerDir.name = "$outerDir.name-$innerDir.name"
-    }
-    moduleList.addAll(outerDir.children)
-}
-
-// Remove the top-level modules which are empty and useless.
-rootProject.children.clear()
-
-// Add the subdirectories as top-level modules.
-rootProject.children.addAll(moduleList)