merge b2g-inbound to mozilla-central
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 09 Dec 2013 09:32:02 +0100
changeset 175182 0204febd31467c1cd357728a45c0e3e508487fd8
parent 175171 7e19e0662879c5a8c1b40a310b7dbf597bd80fe6 (current diff)
parent 175181 b8cc4dd54e13f8ebbd7507a3ba9c3664e1d6c96a (diff)
child 175183 9f12a9fab080f2d363d7424e25b9ffe85ebc3414
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
0204febd3146 / 28.0a1 / 20131209030202 / files
nightly linux64
0204febd3146 / 28.0a1 / 20131209030202 / files
nightly mac
0204febd3146 / 28.0a1 / 20131209030202 / files
nightly win32
0204febd3146 / 28.0a1 / 20131209030202 / files
nightly win64
0204febd3146 / 28.0a1 / 20131209030202 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge b2g-inbound to mozilla-central
content/html/content/src/HTMLMediaElement.cpp
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -1758,17 +1758,39 @@ already_AddRefed<DOMMediaStream>
 HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded)
 {
   nsIDOMWindow* window = OwnerDoc()->GetInnerWindow();
   if (!window) {
     return nullptr;
   }
 
   OutputMediaStream* out = mOutputStreams.AppendElement();
+#ifdef DEBUG
+  // Estimate hints based on the type of the media element
+  // under the preference media.capturestream_hints for the
+  // debug builds only. This allows WebRTC Peer Connection
+  // to behave appropriately when media streams generated
+  // via mozCaptureStream*() are added to the Peer Connection.
+  // This functionality is planned to be used as part of Audio
+  // Quality Performance testing for WebRTC.
+  // Bug932845: Revisit this once hints mechanism is dealt with
+  // holistically.
+  uint8_t hints = 0;
+  if (Preferences::GetBool("media.capturestream_hints.enabled")) {
+    nsCOMPtr<nsIDOMHTMLVideoElement> video = do_QueryObject(this);
+    if (video && GetVideoFrameContainer()) {
+      hints = DOMMediaStream::HINT_CONTENTS_VIDEO | DOMMediaStream::HINT_CONTENTS_AUDIO;
+    } else {
+      hints = DOMMediaStream::HINT_CONTENTS_AUDIO;
+    }
+  }
+  out->mStream = DOMMediaStream::CreateTrackUnionStream(window, hints);
+#else
   out->mStream = DOMMediaStream::CreateTrackUnionStream(window);
+#endif
   nsRefPtr<nsIPrincipal> principal = GetCurrentPrincipal();
   out->mStream->CombineWithPrincipal(principal);
   out->mFinishWhenEnded = aFinishWhenEnded;
 
   mAudioCaptured = true;
   // Block the output stream initially.
   // Decoders are responsible for removing the block while they are playing
   // back into the output stream.
--- a/dom/browser-element/BrowserElementChild.js
+++ b/dom/browser-element/BrowserElementChild.js
@@ -18,22 +18,41 @@ function debug(msg) {
 docShell.isActive = true;
 
 let infos = sendSyncMessage('browser-element-api:call',
                             { 'msg_name': 'hello' })[0];
 docShell.QueryInterface(Ci.nsIDocShellTreeItem).name = infos.name;
 docShell.setFullscreenAllowed(infos.fullscreenAllowed);
 
 
+function parentDocShell(docshell) {
+  if (!docshell) {
+    return null;
+  }
+  let treeitem = docshell.QueryInterface(Ci.nsIDocShellTreeItem);
+  return treeitem.parent ? treeitem.parent.QueryInterface(Ci.nsIDocShell) : null;
+}
+
+function isTopBrowserElement(docShell) {
+  while (docShell) {
+    docShell = parentDocShell(docShell);
+    if (docShell && docShell.isBrowserOrApp) {
+      return false;
+    }
+  }
+  return true;
+}
+
 if (!('BrowserElementIsPreloaded' in this)) {
-  try {
-    if (Services.prefs.getBoolPref("dom.mozInputMethod.enabled")) {
+  if (isTopBrowserElement(docShell) &&
+      Services.prefs.getBoolPref("dom.mozInputMethod.enabled")) {
+    try {
       Services.scriptloader.loadSubScript("chrome://global/content/forms.js");
+    } catch (e) {
     }
-  } catch (e) {
   }
   // Those are produc-specific files that's sometimes unavailable.
   try {
     Services.scriptloader.loadSubScript("chrome://browser/content/ErrorPage.js");
   } catch (e) {
   }
 
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementPanning.js");
--- a/dom/inputmethod/Keyboard.jsm
+++ b/dom/inputmethod/Keyboard.jsm
@@ -4,17 +4,16 @@
 
 'use strict';
 
 this.EXPORTED_SYMBOLS = ['Keyboard'];
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
-const kFormsFrameScript = 'chrome://global/content/forms.js';
 
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
   "@mozilla.org/parentprocessmessagemanager;1", "nsIMessageBroadcaster");
 
 this.Keyboard = {
@@ -75,26 +74,16 @@ this.Keyboard = {
     mm.addMessageListener('Forms:GetText:Result:Error', this);
     mm.addMessageListener('Forms:SetSelectionRange:Result:OK', this);
     mm.addMessageListener('Forms:ReplaceSurroundingText:Result:OK', this);
     mm.addMessageListener('Forms:SendKey:Result:OK', this);
     mm.addMessageListener('Forms:SequenceError', this);
     mm.addMessageListener('Forms:GetContext:Result:OK', this);
     mm.addMessageListener('Forms:SetComposition:Result:OK', this);
     mm.addMessageListener('Forms:EndComposition:Result:OK', this);
-
-    // When not running apps OOP, we need to load forms.js here since this
-    // won't happen from dom/ipc/preload.js
-    try {
-      if (Services.prefs.getBoolPref("dom.ipc.tabs.disabled") === true) {
-        mm.loadFrameScript(kFormsFrameScript, true);
-      }
-    } catch (e) {
-      dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
-    }
   },
 
   receiveMessage: function keyboardReceiveMessage(msg) {
     // If we get a 'Keyboard:XXX' message, check that the sender has the
     // input permission.
     if (msg.name.indexOf("Keyboard:") != -1) {
       if (!this.messageManager) {
         return;
--- a/dom/inputmethod/forms.js
+++ b/dom/inputmethod/forms.js
@@ -21,17 +21,16 @@ XPCOMUtils.defineLazyServiceGetter(Servi
 XPCOMUtils.defineLazyGetter(this, "domWindowUtils", function () {
   return content.QueryInterface(Ci.nsIInterfaceRequestor)
                 .getInterface(Ci.nsIDOMWindowUtils);
 });
 
 const RESIZE_SCROLL_DELAY = 20;
 
 let HTMLDocument = Ci.nsIDOMHTMLDocument;
-let HTMLElement = Ci.nsIDOMHTMLElement;
 let HTMLHtmlElement = Ci.nsIDOMHTMLHtmlElement;
 let HTMLBodyElement = Ci.nsIDOMHTMLBodyElement;
 let HTMLIFrameElement = Ci.nsIDOMHTMLIFrameElement;
 let HTMLInputElement = Ci.nsIDOMHTMLInputElement;
 let HTMLTextAreaElement = Ci.nsIDOMHTMLTextAreaElement;
 let HTMLSelectElement = Ci.nsIDOMHTMLSelectElement;
 let HTMLOptGroupElement = Ci.nsIDOMHTMLOptGroupElement;
 let HTMLOptionElement = Ci.nsIDOMHTMLOptionElement;
@@ -341,22 +340,16 @@ let FormAssistant = {
           target = target.contentDocument ? target.contentDocument.body
                                           : null;
         }
 
         if (!target) {
           break;
         }
 
-        // Only handle the event from our descendants
-        if (target instanceof HTMLElement &&
-            content.window != target.ownerDocument.defaultView.top) {
-          break;
-        }
-
         if (isContentEditable(target)) {
           this.showKeyboard(this.getTopLevelEditable(target));
           this.updateSelection();
           break;
         }
 
         if (this.isFocusableElement(target)) {
           this.showKeyboard(target);
--- a/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js
+++ b/dom/mobilemessage/src/gonk/MobileMessageDatabaseService.js
@@ -1614,20 +1614,24 @@ MobileMessageDatabaseService.prototype =
                                      threadStore, aMessageRecord, aAddresses);
     }, [MESSAGE_STORE_NAME, PARTICIPANT_STORE_NAME, THREAD_STORE_NAME]);
   },
 
   replaceShortMessageOnSave:
     function replaceShortMessageOnSave(aTransaction, aMessageStore,
                                        aParticipantStore, aThreadStore,
                                        aMessageRecord, aAddresses) {
+    let isReplaceTypePid = (aMessageRecord.pid) &&
+                           ((aMessageRecord.pid >= RIL.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_1 &&
+                             aMessageRecord.pid <= RIL.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_7) ||
+                            aMessageRecord.pid == RIL.PDU_PID_RETURN_CALL_MESSAGE);
+
     if (aMessageRecord.type != "sms" ||
         aMessageRecord.delivery != DELIVERY_RECEIVED ||
-        !(aMessageRecord.pid >= RIL.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_1 &&
-          aMessageRecord.pid <= RIL.PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_7)) {
+        !isReplaceTypePid) {
       this.realSaveRecord(aTransaction, aMessageStore, aParticipantStore,
                           aThreadStore, aMessageRecord, aAddresses);
       return;
     }
 
     // 3GPP TS 23.040 subclause 9.2.3.9 "TP-Protocol-Identifier (TP-PID)":
     //
     //   ... the MS shall check the originating address and replace any
--- a/dom/mobilemessage/tests/marionette/test_replace_short_message_type.js
+++ b/dom/mobilemessage/tests/marionette/test_replace_short_message_type.js
@@ -9,17 +9,17 @@ const PDU_SMSC_NONE = "00"; // no SMSC A
 const PDU_FIRST_OCTET = "00"; // RP:no, UDHI:no, SRI:no, MMS:no, MTI:SMS-DELIVER
 
 const PDU_SENDER_0 = "0A912143658709"; // +1234567890
 const PDU_SENDER_1 = "0A912143658719"; // +1234567891
 const SENDER_0 = "+1234567890";
 const SENDER_1 = "+1234567891";
 
 const PDU_PID_NORMAL = "00";
-const PDU_PIDS = ["00", "41", "42", "43", "44", "45", "46", "47"];
+const PDU_PIDS = ["00", "41", "42", "43", "44", "45", "46", "47", "5F"];
 
 const PDU_DCS_NORMAL = "00";
 
 const PDU_TIMESTAMP = "00101000000000"; // 2000/01/01
 
 const PDU_UDL = "01";
 const PDU_UD_A = "41"; // "A"
 const PDU_UD_B = "42"; // "B"
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -19,17 +19,17 @@
 #include "nsJSUtils.h"
 #include "nsJSON.h"
 #include "mozilla/Services.h"
 
 #define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
 
 using namespace mozilla::dom::network;
 
-class MobileConnection::Listener : public nsIMobileConnectionListener
+class MobileConnection::Listener MOZ_FINAL : public nsIMobileConnectionListener
 {
   MobileConnection* mMobileConnection;
 
 public:
   NS_DECL_ISUPPORTS
   NS_FORWARD_SAFE_NSIMOBILECONNECTIONLISTENER(mMobileConnection)
 
   Listener(MobileConnection* aMobileConnection)
@@ -687,9 +687,9 @@ MobileConnection::NotifyIccChanged()
 NS_IMETHODIMP
 MobileConnection::NotifyRadioStateChanged()
 {
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
   return DispatchTrustedEvent(NS_LITERAL_STRING("radiostatechange"));
-}
\ No newline at end of file
+}
--- a/dom/network/src/MobileConnectionArray.cpp
+++ b/dom/network/src/MobileConnectionArray.cpp
@@ -5,19 +5,29 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MobileConnectionArray.h"
 #include "mozilla/dom/MozMobileConnectionArrayBinding.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla::dom::network;
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(MobileConnectionArray,
-                                        mWindow,
-                                        mMobileConnections)
+NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnectionArray)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MobileConnectionArray)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
+  // Notify our mobile connections that we're going away.
+  tmp->DropConnections();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MobileConnectionArray)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(MobileConnectionArray)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileConnectionArray)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileConnectionArray)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MobileConnectionArray)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
@@ -34,16 +44,22 @@ MobileConnectionArray::MobileConnectionA
     mMobileConnections.AppendElement(mobileConnection);
   }
 
   SetIsDOMBinding();
 }
 
 MobileConnectionArray::~MobileConnectionArray()
 {
+  DropConnections();
+}
+
+void
+MobileConnectionArray::DropConnections()
+{
   for (uint32_t i = 0; i < mMobileConnections.Length(); i++) {
     mMobileConnections[i]->Shutdown();
   }
   mMobileConnections.Clear();
 }
 
 nsPIDOMWindow*
 MobileConnectionArray::GetParentObject() const
@@ -73,9 +89,9 @@ MobileConnectionArray::Length() const
 
 nsIDOMMozMobileConnection*
 MobileConnectionArray::IndexedGetter(uint32_t aIndex, bool& aFound) const
 {
   aFound = false;
   aFound = aIndex < mMobileConnections.Length();
 
   return aFound ? mMobileConnections[aIndex] : nullptr;
-}
\ No newline at end of file
+}
--- a/dom/network/src/MobileConnectionArray.h
+++ b/dom/network/src/MobileConnectionArray.h
@@ -40,17 +40,19 @@ public:
   Length() const;
 
   nsIDOMMozMobileConnection*
   IndexedGetter(uint32_t aIndex, bool& aFound) const;
 
 private:
   ~MobileConnectionArray();
 
+  void DropConnections();
+
   nsCOMPtr<nsPIDOMWindow> mWindow;
   nsTArray<nsRefPtr<MobileConnection>> mMobileConnections;
 };
 
 } // namespace network
 } // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_dom_network_MobileConnectionArray_h__
\ No newline at end of file
+#endif // mozilla_dom_network_MobileConnectionArray_h__
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -2051,17 +2051,22 @@ RadioInterface.prototype = {
     // See TS 23.040 9.2.3.24.2
 
     let mwi = message.mwi;
     if (mwi) {
       mwi.returnNumber = message.sender;
       mwi.returnMessage = message.fullBody;
       gMessageManager.sendVoicemailMessage("RIL:VoicemailNotification",
                                            this.clientId, mwi);
-      return true;
+
+      // Dicarded MWI comes without text body.
+      // Hence, we discard it here after notifying the MWI status.
+      if (mwi.discard) {
+        return true;
+      }
     }
 
     let notifyReceived = function notifyReceived(rv, domMessage) {
       let success = Components.isSuccessCode(rv);
 
       // Acknowledge the reception of the SMS.
       // Note: Ack has been done by modem for NEW_SMS_ON_SIM
       if (message.simStatus === undefined) {
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -6960,27 +6960,16 @@ let GsmPDUHelper = {
     switch (msg.epid & 0xC0) {
       case 0x40:
         // Bit 7..0 = 01xxxxxx
         switch (msg.epid) {
           case PDU_PID_SHORT_MESSAGE_TYPE_0:
           case PDU_PID_ANSI_136_R_DATA:
           case PDU_PID_USIM_DATA_DOWNLOAD:
             return;
-          case PDU_PID_RETURN_CALL_MESSAGE:
-            // Level 1 of message waiting indication:
-            // Only a return call message is provided
-            let mwi = msg.mwi = {};
-
-            // TODO: When should we de-activate the level 1 indicator?
-            mwi.active = true;
-            mwi.discard = false;
-            mwi.msgCount = GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN;
-            if (DEBUG) debug("TP-PID got return call message: " + msg.sender);
-            return;
         }
         break;
     }
 
     msg.epid = PDU_PID_DEFAULT;
   },
 
   /**
--- a/dom/voicemail/test/marionette/test_voicemail_statuschanged.js
+++ b/dom/voicemail/test/marionette/test_voicemail_statuschanged.js
@@ -51,54 +51,25 @@ function isVoicemailStatus(status) {
   is(voicemail.getStatus().messageCount, status.messageCount);
   is(voicemail.getStatus().returnNumber, status.returnNumber);
   is(voicemail.getStatus().returnMessage, status.returnMessage);
 }
 
 const MWI_PDU_PREFIX = "0000";
 const MWI_PDU_UDH_PREFIX = "0040";
 const MWI_PID_DEFAULT = "00";
-const MWI_PID_RETURN_CALL_MSG = "5F";
-const MWI_DCS_DATA_MSG = "F0";
 const MWI_DCS_DISCARD_INACTIVE = "C0";
 const MWI_DCS_DISCARD_ACTIVE = "C8";
 const MWI_TIMESTAMP = "00000000000000";
 
-const MWI_LEVEL1_SENDER = "+15125551234";
-const MWI_LEVEL1_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL1_SENDER);
 const MWI_DEFAULT_BODY = "1 new voicemail";
 const MWI_UD_DEFAULT = PDUBuilder.buildUserData({
   body: MWI_DEFAULT_BODY
 });
 
-// Level 1 Message Waiting is just a return call message
-const MWI_LEVEL1_PDU =
-  MWI_PDU_PREFIX +
-  MWI_LEVEL1_PDU_ADDRESS +
-  MWI_PID_RETURN_CALL_MSG +
-  MWI_DCS_DATA_MSG +
-  MWI_TIMESTAMP +
-  MWI_UD_DEFAULT;
-
-function testLevel1Indicator() {
-
-  function onLevel1Indicator(event) {
-    let status = event.status;
-    // TODO: bug 905228 - MozVoicemailStatus is not defined.
-    //ok(status instanceof MozVoicemailStatus);
-    is(status.hasMessages, true);
-    is(status.messageCount, -1);
-    is(status.returnNumber, MWI_LEVEL1_SENDER);
-    is(status.returnMessage, MWI_DEFAULT_BODY);
-    isVoicemailStatus(status);
-  }
-
-  sendIndicatorPDU(MWI_LEVEL1_PDU, onLevel1Indicator, testLevel2DiscardActive);
-}
-
 const MWI_LEVEL2_SENDER = "+15125551235";
 const MWI_LEVEL2_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL2_SENDER);
 const MWI_LEVEL2_DISCARD_ACTIVE_PDU =
   MWI_PDU_PREFIX +
   MWI_LEVEL2_PDU_ADDRESS +
   MWI_PID_DEFAULT +
   MWI_DCS_DISCARD_ACTIVE +
   MWI_TIMESTAMP +
@@ -229,9 +200,9 @@ function testLevel3DiscardInactive() {
   sendIndicatorPDU(MWI_LEVEL3_DISCARD_INACTIVE_PDU, onLevel3Inactive, cleanUp);
 }
 
 function cleanUp() {
   SpecialPowers.removePermission("voicemail", document);
   finish();
 }
 
-testLevel1Indicator();
+testLevel2DiscardActive();
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -753,19 +753,21 @@ void MediaPipelineTransmit::PipelineList
     TrackRate rate,
     AudioChunk& chunk) {
   // TODO(ekr@rtfm.com): Do more than one channel
   nsAutoArrayPtr<int16_t> samples(new int16_t[chunk.mDuration]);
 
   if (chunk.mBuffer) {
     switch (chunk.mBufferFormat) {
       case AUDIO_FORMAT_FLOAT32:
-        MOZ_MTLOG(ML_ERROR, "Can't process audio except in 16-bit PCM yet");
-        MOZ_ASSERT(PR_FALSE);
-        return;
+        {
+          const float* buf = static_cast<const float *>(chunk.mChannelData[0]);
+          ConvertAudioSamplesWithScale(buf, static_cast<int16_t*>(samples),
+                                       chunk.mDuration, chunk.mVolume);
+        }
         break;
       case AUDIO_FORMAT_S16:
         {
           const short* buf = static_cast<const short *>(chunk.mChannelData[0]);
           ConvertAudioSamplesWithScale(buf, samples, chunk.mDuration, chunk.mVolume);
         }
         break;
       default:
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/java/src/org/webrtc/videoengine/VideoCaptureAndroid.java
@@ -7,16 +7,17 @@
  *  in the file PATENTS.  All contributing project authors may
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
 package org.webrtc.videoengine;
 
 import java.io.IOException;
 import java.util.Locale;
+import java.util.List;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.webrtc.videoengine.CaptureCapabilityAndroid;
 import org.webrtc.videoengine.VideoCaptureDeviceInfoAndroid.AndroidVideoCaptureDevice;
 
 import android.graphics.ImageFormat;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -280,16 +281,22 @@ public class VideoCaptureAndroid impleme
                     new CaptureCapabilityAndroid();
             currentCapability.width = width;
             currentCapability.height = height;
             currentCapability.maxFPS = frameRate;
             PixelFormat.getPixelFormatInfo(PIXEL_FORMAT, pixelFormat);
 
 
             Camera.Parameters parameters = camera.getParameters();
+
+            List<String> focusModeList = parameters.getSupportedFocusModes();
+            if (focusModeList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
+                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+            }
+
             parameters.setPreviewSize(currentCapability.width,
                     currentCapability.height);
             parameters.setPreviewFormat(PIXEL_FORMAT);
             parameters.setPreviewFrameRate(currentCapability.maxFPS);
             camera.setParameters(parameters);
 
             int bufSize = width * height * pixelFormat.bitsPerPixel / 8;
             byte[] buffer = null;