diff --git a/bbb-lti/Dockerfile b/bbb-lti/Dockerfile
index 4503f2d172e525085026332f16b97e38b46f4a2c..318681aa416f09e1f6ec6619271eb2771f856dc7 100644
--- a/bbb-lti/Dockerfile
+++ b/bbb-lti/Dockerfile
@@ -33,6 +33,7 @@ RUN cd /source \
  && sed -i "s|\(<lticp:name>\)[^<]*|\1$vendor_name|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \
  && sed -i "s|\(<lticp:description>\)[^<]*|\1$vendor_description|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \
  && sed -i "s|\(<lticp:url>\)[^<]*|\1$vendor_url|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \
+ && sed -i "s|BigBlueButton|$title|g" grails-app/i18n/*.properties \
  && grails war
 
 FROM tomcat:7-jre8
@@ -44,9 +45,8 @@ RUN rm -r webapps/*
 
 COPY --from=builder /source/target/lti-*.war webapps/lti.war
 
-RUN unzip -q webapps/lti.war -d webapps/lti \
- && rm webapps/lti.war
-
 COPY docker-entrypoint.sh /usr/local/bin/
 
+ENV LTI_CONTEXT_PATH lti
+
 CMD ["docker-entrypoint.sh"]
diff --git a/bbb-lti/docker-entrypoint.sh b/bbb-lti/docker-entrypoint.sh
index 608af0aa7ad42fa92ec1d1b73f85021484974b78..83b353b124712f950c79c0692d05976cab260d14 100755
--- a/bbb-lti/docker-entrypoint.sh
+++ b/bbb-lti/docker-entrypoint.sh
@@ -1,7 +1,13 @@
 #!/bin/bash -xe
 
-export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -DbigbluebuttonSalt=$BIGBLUEBUTTON_SHARED_SECRET -DbigbluebuttonURL=$BIGBLUEBUTTON_URL -DltiEndPoint=$LTI_ENDPOINT -DltiConsumers=$LTI_CONSUMERS -DltiAllRecordedByDefault=$RECORDED_BY_DEFAULT"
+export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -DbigbluebuttonSalt=$BIGBLUEBUTTON_SHARED_SECRET -DbigbluebuttonURL=$BIGBLUEBUTTON_URL -DltiEndPoint=$LTI_ENDPOINT -DltiConsumers=$LTI_CONSUMERS -DltiAllRecordedByDefault=$RECORDED_BY_DEFAULT -DltiCanvasPlacements=$LTI_CANVAS_PLACEMENTS -DltiCanvasPlacementName=$LTI_CANVAS_PLACEMENT_NAME"
 sed -i "s|^securerandom\.source=.*|securerandom.source=file:/dev/./urandom|g" $JAVA_HOME/lib/security/java.security
 
+if [ -f webapps/lti.war ]; then
+  mkdir -p webapps/$LTI_CONTEXT_PATH
+  unzip -q webapps/lti.war -d webapps/$LTI_CONTEXT_PATH
+  rm webapps/lti.war
+fi
+
 catalina.sh run
 
diff --git a/bbb-lti/grails-app/conf/lti-config.properties b/bbb-lti/grails-app/conf/lti-config.properties
index 6984fce90df8f13dabb302aa1fa86434e59903b5..7653c5d16a3a6c9991266f15056057a42671cd3e 100644
--- a/bbb-lti/grails-app/conf/lti-config.properties
+++ b/bbb-lti/grails-app/conf/lti-config.properties
@@ -44,6 +44,10 @@ ltiRestrictedAccess=true
 # Sets all the meetings to be recorded by default
 # Format: [<false>|true]
 ltiAllRecordedByDefault=false
+# The list of placements enabled on lti service.
+# Format: assignment_menu,assignment_selection,assignments_menu,collaboration,course_navigation,course_home_sub_navigation,course_settings_sub_navigation
+ltiCanvasPlacements=
+ltiCanvasPlacementName=BigBlueButton
 
 #----------------------------------------------------
 # Inject configuration values into BigbluebuttonSrvice beans
@@ -57,3 +61,5 @@ beans.ltiService.consumers=${ltiConsumers}
 beans.ltiService.mode=${ltiMode}
 beans.ltiService.restrictedAccess=${ltiRestrictedAccess}
 beans.ltiService.recordedByDefault=${ltiAllRecordedByDefault}
+beans.ltiService.canvasPlacements=${ltiCanvasPlacements}
+beans.ltiService.canvasPlacementName=${ltiCanvasPlacementName}
diff --git a/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy b/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy
index 87a85f90519459ce007461fb734e0325f99b19fb..60c8c4dd53eee8d97aa011c0975bfec48acd5fb4 100644
--- a/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy
+++ b/bbb-lti/grails-app/controllers/org/bigbluebutton/ToolController.groovy
@@ -60,7 +60,9 @@ class ToolController {
             return
         }
         // On post request proceed with the launch.
-        def endPoint = ltiService.getScheme(request) + "://" + ltiService.endPoint + "/" + grailsApplication.metadata['app.name'] + "/" + params.get("controller") + (params.get("format") != null ? "." + params.get("format") : "")
+        def schemeHeader = request.getHeader("X-Forwarded-Proto")
+        def scheme = schemeHeader == null ? ltiService.getScheme(request) : schemeHeader
+        def endPoint = scheme + "://" + ltiService.endPoint + "/" + grailsApplication.metadata['app.name'] + "/" + params.get("controller") + (params.get("format") != null ? "." + params.get("format") : "")
         log.info "endPoint: " + endPoint
         ArrayList<String> missingParams = new ArrayList<String>()
 
@@ -177,7 +179,7 @@ class ToolController {
     private void setLocalization(Map<String, String> params){
         String locale = params.get(Parameter.LAUNCH_LOCALE)
         locale = (locale == null || locale.equals("")?"en":locale)
-        String[] localeCodes = locale.split("_")
+        String[] localeCodes = locale.split("[_-]")
         // Localize the default welcome message
         session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'] = new Locale(localeCodes[0])
         if (localeCodes.length > 1) {
@@ -326,10 +328,23 @@ class ToolController {
             recording.put("unixDate", startTime / 1000)
             // Add sanitized thumbnails
             recording.put("thumbnails", sanitizeThumbnails(recording.playback.format))
+            recording.put("playbacks", sanitizePlayback(recording.playback.format))
         }
         return recordings
     }
 
+    private List<Object> sanitizePlayback(Object format) {
+        def response = new ArrayList<Object>()
+        if (format instanceof Map<?,?>) {
+            response.add(format)
+        } else if (format instanceof Collection<?>) {
+            response = new ArrayList(format)
+        } else {
+            response = format
+        }
+        return response
+    }
+
     private List<Object> sanitizeThumbnails(Object format) {
         if (format.preview == null || format.preview.images == null || format.preview.images.image == null) {
             return new ArrayList()
@@ -347,6 +362,26 @@ class ToolController {
         def icon = 'http://' + lti_endpoint + '/assets/icon.ico'
         def secure_icon = 'https://' + lti_endpoint + '/assets/icon.ico'
         def isSSLEnabled = ltiService.isSSLEnabled('https://' + lti_endpoint + '/tool/test')
+        def extension_url = isSSLEnabled ? secure_launch_url : launch_url
+        def extension_icon = isSSLEnabled ? secure_icon : icon
+        def canvasPlacements = ''
+        def canvasPlacementsList = ltiService.canvasPlacements
+        if (canvasPlacementsList.length > 0) {
+            canvasPlacements += '' +
+                '    <blti:extensions platform="canvas.instructure.com">'
+            canvasPlacementsList.each { placement ->
+                canvasPlacements += '' +
+                    '        <lticm:options name="' + placement + '">' +
+                    '          <lticm:property name="canvas_icon_class">icon-lti</lticm:property>' +
+                    '          <lticm:property name="icon_url">' + extension_icon + '</lticm:property>' +
+                    '          <lticm:property name="text">' + ltiService.canvasPlacementName + '</lticm:property>' +
+                    '          <lticm:property name="url">' + extension_url + '</lticm:property>' +
+                    '        </lticm:options>'
+            }
+            canvasPlacements += '' +
+                '    </blti:extensions>'
+        }
+
         def cartridge = '' +
                 '<?xml version="1.0" encoding="UTF-8"?>' +
                 '<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"' +
@@ -370,6 +405,7 @@ class ToolController {
                 '        <lticp:description>Open source web conferencing system for distance learning.</lticp:description>' +
                 '        <lticp:url>http://www.bigbluebutton.org/</lticp:url>' +
                 '    </blti:vendor>' +
+                canvasPlacements +
                 '    <cartridge_bundle identifierref="BLTI001_Bundle"/>' +
                 '    <cartridge_icon identifierref="BLTI001_Icon"/>' +
                 '</cartridge_basiclti_link>'
diff --git a/bbb-lti/grails-app/i18n/messages.properties b/bbb-lti/grails-app/i18n/messages.properties
index 4b708fbecba231e618ff510beff21645a3ccdddd..87b6e6e6706e4632b7902daeb1d3e95c2938c5f3 100644
--- a/bbb-lti/grails-app/i18n/messages.properties
+++ b/bbb-lti/grails-app/i18n/messages.properties
@@ -27,8 +27,9 @@ tool.view.app=BigBlueButton
 tool.view.title=BigBlueButton LTI Interface
 tool.view.join=Join Meeting
 tool.view.recording=Recording
-tool.view.recording.format.presentation=presentation
-tool.view.recording.format.video=video
+tool.view.recording.format.presentation=Watch
+tool.view.recording.format.video=Video
+tool.view.recording.format.presentation_video=Download
 tool.view.recording.delete.confirmation=Are you sure to permanently delete this recording?
 tool.view.recording.delete.confirmation.warning=Warning
 tool.view.recording.delete.confirmation.yes=Yes
diff --git a/bbb-lti/grails-app/i18n/messages_pt.properties b/bbb-lti/grails-app/i18n/messages_pt.properties
new file mode 100644
index 0000000000000000000000000000000000000000..5ab0946088d969da5e35873a0eeb2090c177390a
--- /dev/null
+++ b/bbb-lti/grails-app/i18n/messages_pt.properties
@@ -0,0 +1,48 @@
+#
+# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+#
+# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+#
+
+# The welcome.header can be static, however if you want the name of the activity (meeting) to be injected use {0} as part of the text
+# {1} can be used to inject the name of the course
+bigbluebutton.welcome.header=Bem-vindo à sala <b>{0}</b>!
+bigbluebutton.welcome.footer=Para saber mais sobre o BigBlueButton, acesse nossos <a href=\"event:http://www.bigbluebutton.org/content/videos\"><u>vídeos tutoriais</u></a>.<br><br>Para habilitar o áudio, clique no ícone do hearset. <b>Utilize um headset para evitar ruídos na sessão.
+bigbluebutton.welcome.record=Esta sessão está sendo gravada
+bigbluebutton.welcome.duration=A duração máxima desta sessão é de {0} minutos
+
+tool.view.app=BigBlueButton
+tool.view.title=Inteface LTI do BigBlueButton
+tool.view.join=Entrar na sessão
+tool.view.recording=Gravação
+tool.view.recording.format.presentation=Assistir
+tool.view.recording.format.video=Vídeo
+tool.view.recording.format.presentation_video=Baixar
+tool.view.recording.delete.confirmation=Você tem certeza que deseja excluir permanentemente esta gravação?
+tool.view.recording.delete.confirmation.warning=Aviso
+tool.view.recording.delete.confirmation.yes=Sim
+tool.view.recording.delete.confirmation.no=Não
+tool.view.recording.publish=Publicar
+tool.view.recording.unpublish=Esconder
+tool.view.recording.delete=Excluir
+tool.view.activity=Atividade
+tool.view.description=Descrição
+tool.view.preview=Preview
+tool.view.date=Data
+tool.view.duration=Duração
+tool.view.actions=Ações
+tool.view.dateFormat=E, MM dd, yyyy HH:mm:ss Z
+
+tool.error.general=Não foi possível estabelecer a coenxão.
diff --git a/bbb-lti/grails-app/services/org/bigbluebutton/LtiService.groovy b/bbb-lti/grails-app/services/org/bigbluebutton/LtiService.groovy
index 2465c8e330e1c949e5d50538ae8eb8f0aaa38fd9..b7d103bf73c4e6d0e44195878978952330f82f5e 100644
--- a/bbb-lti/grails-app/services/org/bigbluebutton/LtiService.groovy
+++ b/bbb-lti/grails-app/services/org/bigbluebutton/LtiService.groovy
@@ -33,6 +33,8 @@ class LtiService {
     def mode = "simple"
     def restrictedAccess = "true"
     def recordedByDefault = "false"
+    def canvasPlacements = ""
+    def canvasPlacementName = "BigBlueButton"
 
     Map<String, String> consumerMap
 
@@ -144,4 +146,9 @@ class LtiService {
     def String getScheme(request) {
         return request.isSecure() ? "https" : "http"
     }
+
+    def String[] getCanvasPlacements() {
+        return this.canvasPlacements
+    }
 }
+
diff --git a/bbb-lti/grails-app/views/tool/index.gsp b/bbb-lti/grails-app/views/tool/index.gsp
index e733636a2d61803f1d44afcf9c099f58c8b8f195..183e1c163cb75944b4f62ecabec5469076a9375b 100644
--- a/bbb-lti/grails-app/views/tool/index.gsp
+++ b/bbb-lti/grails-app/views/tool/index.gsp
@@ -41,8 +41,8 @@
                 <tr class="r0 lastrow">
                     <td class="cell c0" style="text-align:center;">
                     <g:if test="${r.published}">
-                        <g:each in="${r.playback}" var="format">
-                            <a title="<g:message code="tool.view.recording.format.${format.getValue().type}" />" target="_new" href="${format.getValue().url}"><g:message code="tool.view.recording.format.${format.getValue().type}" /></a>&#32;
+                        <g:each in="${r.playbacks}" var="format">
+                            <a title="<g:message code="tool.view.recording.format.${format.type}" />" target="_new" href="${format.url}"><g:message code="tool.view.recording.format.${format.type}" /></a><br>
                         </g:each>
                     </g:if>
                     </td>