Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2013-07-17 14:34:19 -04:00
commit 2e2e0887ff
14 changed files with 351 additions and 63 deletions

View File

@ -1,4 +1,4 @@
{
"revision": "61262845a414403a1507ceb1afebfd4f8139e0f5",
"revision": "34a53279dad496e201616f5e782bd58ef6d38ae5",
"repo_path": "/integration/gaia-central"
}

View File

@ -525,6 +525,7 @@
@BINPATH@/components/ActivityProxy.js
@BINPATH@/components/ActivityRequestHandler.js
@BINPATH@/components/ActivityWrapper.js
@BINPATH@/components/ActivityMessageConfigurator.js
@BINPATH@/components/TCPSocket.js
@BINPATH@/components/TCPSocketParentIntermediary.js

View File

@ -4,6 +4,9 @@ contract @mozilla.org/dom/activities/proxy;1 {ba9bd5cb-76a0-4ecf-a7b3-d2f7c43c59
component {5430d6f9-32d6-4924-ba39-6b6d1b093cd6} ActivityWrapper.js
contract @mozilla.org/dom/system-messages/wrapper/activity;1 {5430d6f9-32d6-4924-ba39-6b6d1b093cd6}
component {d2296daa-c406-4c5e-b698-e5f2c1715798} ActivityMessageConfigurator.js
contract @mozilla.org/dom/system-messages/configurator/activity;1 {d2296daa-c406-4c5e-b698-e5f2c1715798}
component {9326952a-dbe3-4d81-a51f-d9c160d96d6b} ActivityRequestHandler.js
contract @mozilla.org/dom/activities/request-handler;1 {9326952a-dbe3-4d81-a51f-d9c160d96d6b}

View File

@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function debug(aMsg) {
// dump("-- ActivityMessageConfigurator.js " + Date.now() + " : " + aMsg + "\n");
}
/**
* nsISystemMessagesConfigurator implementation.
*/
function ActivityMessageConfigurator() {
debug("ActivityMessageConfigurator");
}
ActivityMessageConfigurator.prototype = {
get safeToSendBeforeRunningApp() {
debug("safeToSendBeforeRunningApp returning false");
return false;
},
classID: Components.ID("{d2296daa-c406-4c5e-b698-e5f2c1715798}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesConfigurator])
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivityMessageConfigurator]);

View File

@ -16,6 +16,7 @@ CPP_SOURCES += [
EXTRA_COMPONENTS += [
'Activities.manifest',
'ActivityMessageConfigurator.js',
'ActivityOptions.js',
'ActivityProxy.js',
'ActivityRequestHandler.js',

View File

@ -48,6 +48,12 @@ function debug(aMsg) {
}
let defaultMessageConfigurator = {
get safeToSendBeforeRunningApp() {
return true;
}
};
const MSG_SENT_SUCCESS = 0;
const MSG_SENT_FAILURE_PERM_DENIED = 1;
const MSG_SENT_FAILURE_APP_NOT_RUNNING = 2;
@ -71,6 +77,8 @@ function SystemMessageInternal() {
this._cpuWakeLocks = {};
this._configurators = {};
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, "webapps-registry-start", false);
Services.obs.addObserver(this, "webapps-registry-ready", false);
@ -83,6 +91,22 @@ function SystemMessageInternal() {
SystemMessageInternal.prototype = {
_getMessageConfigurator: function _getMessageConfigurator(aType) {
debug("_getMessageConfigurator for type: " + aType);
if (this._configurators[aType] === undefined) {
let contractID = "@mozilla.org/dom/system-messages/configurator/" + aType + ";1";
if (contractID in Cc) {
debug(contractID + " is registered, creating an instance");
this._configurators[aType] =
Cc[contractID].createInstance(Ci.nsISystemMessagesConfigurator);
} else {
debug(contractID + "is not registered, caching the answer");
this._configurators[aType] = null;
}
}
return this._configurators[aType] || defaultMessageConfigurator;
},
_cancelCpuWakeLock: function _cancelCpuWakeLock(aPageKey) {
let cpuWakeLock = this._cpuWakeLocks[aPageKey];
if (cpuWakeLock) {
@ -547,36 +571,42 @@ SystemMessageInternal.prototype = {
let appPageIsRunning = false;
let pageKey = this._createKeyForPage({ type: aType,
manifest: aManifestURI,
uri: aPageURI })
uri: aPageURI });
let targets = this._listeners[aManifestURI];
if (targets) {
for (let index = 0; index < targets.length; ++index) {
let target = targets[index];
// We only need to send the system message to the targets (processes)
// which contain the window page that matches the manifest/page URL of
// the destination of system message.
if (target.winCounts[aPageURI] === undefined) {
continue;
// Tries to send the message to a previously opened app only if it's safe
// to do so. Generically, it's safe to send the message if the app isn't
// going to be reloaded. And it's not safe otherwise
if (this._getMessageConfigurator(aType).safeToSendBeforeRunningApp) {
let targets = this._listeners[aManifestURI];
if (targets) {
for (let index = 0; index < targets.length; ++index) {
let target = targets[index];
// We only need to send the system message to the targets (processes)
// which contain the window page that matches the manifest/page URL of
// the destination of system message.
if (target.winCounts[aPageURI] === undefined) {
continue;
}
appPageIsRunning = true;
// We need to acquire a CPU wake lock for that page and expect that
// we'll receive a "SystemMessageManager:HandleMessagesDone" message
// when the page finishes handling the system message. At that point,
// we'll release the lock we acquired.
this._acquireCpuWakeLock(pageKey);
// Multiple windows can share the same target (process), the content
// window needs to check if the manifest/page URL is matched. Only
// *one* window should handle the system message.
let manager = target.target;
manager.sendAsyncMessage("SystemMessageManager:Message",
{ type: aType,
msg: aMessage,
manifest: aManifestURI,
uri: aPageURI,
msgID: aMessageID });
}
appPageIsRunning = true;
// We need to acquire a CPU wake lock for that page and expect that
// we'll receive a "SystemMessageManager:HandleMessagesDone" message
// when the page finishes handling the system message. At that point,
// we'll release the lock we acquired.
this._acquireCpuWakeLock(pageKey);
// Multiple windows can share the same target (process), the content
// window needs to check if the manifest/page URL is matched. Only
// *one* window should handle the system message.
let manager = target.target;
manager.sendAsyncMessage("SystemMessageManager:Message",
{ type: aType,
msg: aMessage,
manifest: aManifestURI,
uri: aPageURI,
msgID: aMessageID });
}
}

View File

@ -47,3 +47,18 @@ interface nsISystemMessagesWrapper: nsISupports
*/
jsval wrapMessage(in jsval message, in nsIDOMWindow window);
};
/*
* Implements an interface to allow specific message types to
* configure some behaviors
*/
[scriptable, uuid(8a71981b-a462-4697-b63c-925997f9d47b)]
interface nsISystemMessagesConfigurator: nsISupports
{
/*
* Will be true if this type of system messages is safe to send
* before the frontend has activated the app to process it.
* The default value (if there's no overriding class) is true
*/
readonly attribute boolean safeToSendBeforeRunningApp;
};

View File

@ -41,13 +41,7 @@ AudioChannelManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
void
AudioChannelManager::Notify(const SwitchEvent& aEvent)
{
if (aEvent.status() == SWITCH_STATE_ON ||
aEvent.status() == SWITCH_STATE_HEADSET ||
aEvent.status() == SWITCH_STATE_HEADPHONE) {
mState = SWITCH_STATE_ON;
} else {
mState = SWITCH_STATE_OFF;
}
mState = aEvent.status();
DispatchTrustedEvent(NS_LITERAL_STRING("headphoneschange"));
}

View File

@ -43,7 +43,8 @@ public:
bool Headphones() const
{
return mState == hal::SWITCH_STATE_ON;
MOZ_ASSERT(mState != hal::SWITCH_STATE_UNKNOWN);
return mState != hal::SWITCH_STATE_OFF;
}
IMPL_EVENT_HANDLER(headphoneschange)

View File

@ -23,6 +23,7 @@
#include "mozilla/Hal.h"
#include "mozilla/Services.h"
#include "base/message_loop.h"
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
@ -60,6 +61,7 @@ static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
// A bitwise variable for recording what kind of headset is attached.
static int sHeadsetState;
static const int kBtSampleRate = 8000;
static bool sSwitchDone = true;
class RecoverTask : public nsRunnable
{
@ -116,6 +118,14 @@ IsDeviceOn(audio_devices_t device)
return false;
}
static void ProcessDelayedAudioRoute(SwitchState aState)
{
if (sSwitchDone)
return;
InternalSetAudioRoutes(aState);
sSwitchDone = true;
}
NS_IMPL_ISUPPORTS2(AudioManager, nsIAudioManager, nsIObserver)
static AudioSystem::audio_devices
@ -269,8 +279,16 @@ class HeadphoneSwitchObserver : public SwitchObserver
{
public:
void Notify(const SwitchEvent& aEvent) {
InternalSetAudioRoutes(aEvent.status());
NotifyHeadphonesStatus(aEvent.status());
// When user pulled out the headset, a delay of routing here can avoid the leakage of audio from speaker.
if (aEvent.status() == SWITCH_STATE_OFF && sSwitchDone) {
MessageLoop::current()->PostDelayedTask(
FROM_HERE, NewRunnableFunction(&ProcessDelayedAudioRoute, SWITCH_STATE_OFF), 1000);
sSwitchDone = false;
} else if (aEvent.status() != SWITCH_STATE_OFF) {
InternalSetAudioRoutes(aEvent.status());
sSwitchDone = true;
}
}
};

View File

@ -132,6 +132,9 @@ this.REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
this.REQUEST_VOICE_RADIO_TECH = 108;
this.REQUEST_DIAL_EMERGENCY_CALL = 10016;
// Mozilla-specific request codes
this.REQUEST_GET_UNLOCK_RETRY_COUNT = 150;
// Akami/Maguro specific parcel types.
this.REQUEST_IMS_REGISTRATION_STATE = 106;
this.REQUEST_IMS_SEND_SMS = 107;
@ -591,6 +594,24 @@ this.ICC_SERVICE_CLASS_PACKET = (1 << 6);
this.ICC_SERVICE_CLASS_PAD = (1 << 7);
this.ICC_SERVICE_CLASS_MAX = (1 << 7); // Max ICC_SERVICE_CLASS value
// ICC lock-selection codes
// TS 27.007, clause 8.65, +CPINR
this.ICC_SEL_CODE_SIM_PIN = "SIM PIN";
this.ICC_SEL_CODE_SIM_PUK = "SIM PUK";
this.ICC_SEL_CODE_PH_SIM_PIN = "PH-SIM PIN";
this.ICC_SEL_CODE_PH_FSIM_PIN = "PH-FSIM PIN";
this.ICC_SEL_CODE_PH_FSIM_PUK = "PH-FSIM PUK";
this.ICC_SEL_CODE_SIM_PIN2 = "SIM PIN2";
this.ICC_SEL_CODE_SIM_PUK2 = "SIM PUK2";
this.ICC_SEL_CODE_PH_NET_PIN = "PH-NET PIN";
this.ICC_SEL_CODE_PH_NET_PUK = "PH-NET PUK";
this.ICC_SEL_CODE_PH_NETSUB_PIN = "PH-NETSUB PIN";
this.ICC_SEL_CODE_PH_NETSUB_PUK = "PH-NETSUB PUK";
this.ICC_SEL_CODE_PH_SP_PIN = "PH-SP PIN";
this.ICC_SEL_CODE_PH_SP_PUK = "PH-SP PUK";
this.ICC_SEL_CODE_PH_CORP_PIN = "PH-CORP PIN";
this.ICC_SEL_CODE_PH_CORP_PUK = "PH-CORP PUK";
this.ICC_USIM_TYPE1_TAG = 0xa8;
this.ICC_USIM_TYPE2_TAG = 0xa9;
this.ICC_USIM_TYPE3_TAG = 0xaa;

View File

@ -87,6 +87,8 @@ let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = libcutils.property_get("ro.moz.
let RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = libcutils.property_get("ro.moz.ril.simstate_extra_field", "false") === "true";
// Needed for call-waiting on Peak device
let RILQUIRKS_EXTRA_UINT32_2ND_CALL = libcutils.property_get("ro.moz.ril.extra_int_2nd_call", "false") == "true";
// On the emulator we support querying the number of lock retries
let RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT = libcutils.property_get("ro.moz.ril.have_query_icc_lock_retry_count", "false") == "true";
// Marker object.
let PENDING_NETWORK_TYPE = {};
@ -1198,32 +1200,54 @@ let RIL = {
/**
* Helper function for fetching the number of unlock retries of ICC locks.
*
* We only query the retry count when we're on the emulator. The phones do
* not support the request id and their rild doesn't return an error.
*/
iccGetCardLockRetryCount: function iccGetCardLockRetryCount(options) {
switch (options.lockType) {
case "pin":
case "puk":
case "pin2":
case "puk2":
case "nck":
case "cck":
case "spck":
options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
options.success = false;
this.sendDOMMessage(options);
return;
default:
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
options.success = false;
this.sendDOMMessage(options);
return;
var selCode = {
pin: ICC_SEL_CODE_SIM_PIN,
puk: ICC_SEL_CODE_SIM_PUK,
pin2: ICC_SEL_CODE_SIM_PIN2,
puk2: ICC_SEL_CODE_SIM_PUK2,
nck: ICC_SEL_CODE_PH_NET_PIN,
cck: ICC_SEL_CODE_PH_CORP_PIN,
spck: ICC_SEL_CODE_PH_SP_PIN
};
if (typeof(selCode[options.lockType]) === 'undefined') {
/* unknown lock type */
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
options.success = false;
this.sendDOMMessage(options);
return;
}
// TODO: We currently don't have a way for
// reading the retry count. See bug 868896.
options.retryCount = 0;
options.success = true;
this.sendDOMMessage(options);
if (RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT) {
/* Only the emulator supports this request, ... */
options.selCode = selCode[options.lockType];
this.queryICCLockRetryCount(options);
} else {
/* ... while the phones do not. */
options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
options.success = false;
this.sendDOMMessage(options);
}
},
/**
* Query ICC lock retry count.
*
* @param selCode
* One of ICC_SEL_CODE_*.
* @param serviceClass
* One of ICC_SERVICE_CLASS_*.
*/
queryICCLockRetryCount: function queryICCLockRetryCount(options) {
Buf.newParcel(REQUEST_GET_UNLOCK_RETRY_COUNT, options);
Buf.writeUint32(1);
Buf.writeString(options.selCode);
Buf.sendParcel();
},
/**
@ -1455,6 +1479,16 @@ let RIL = {
Buf.sendParcel();
},
/**
* Queries current CLIP status.
*
* (MMI request for code "*#30#")
*
*/
queryCLIP: function queryCLIP(options) {
Buf.simpleRequest(REQUEST_QUERY_CLIP, options);
},
/**
* Set screen state.
*
@ -2397,6 +2431,17 @@ let RIL = {
this.sendDOMMessage(options);
return;
// CLIP
case MMI_SC_CLIP:
options.mmiServiceCode = MMI_KS_SC_CLIP;
options.procedure = mmi.procedure;
if (options.procedure === MMI_PROCEDURE_INTERROGATION) {
this.queryCLIP(options);
} else {
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED, MMI_KS_SC_CLIP);
}
return;
// Call barring
case MMI_SC_BAOC:
case MMI_SC_BAOIC:
@ -2408,8 +2453,6 @@ let RIL = {
case MMI_SC_BA_MT:
// Call waiting
case MMI_SC_CALL_WAITING:
// CLIP
case MMI_SC_CLIP:
// CLIR
case MMI_SC_CLIR:
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED);
@ -5150,7 +5193,44 @@ RIL[REQUEST_BASEBAND_VERSION] = function REQUEST_BASEBAND_VERSION(length, option
RIL[REQUEST_SEPARATE_CONNECTION] = null;
RIL[REQUEST_SET_MUTE] = null;
RIL[REQUEST_GET_MUTE] = null;
RIL[REQUEST_QUERY_CLIP] = null;
RIL[REQUEST_QUERY_CLIP] = function REQUEST_QUERY_CLIP(length, options) {
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
this.sendDOMMessage(options);
return;
}
let bufLength = Buf.readUint32();
if (!bufLength) {
options.success = false;
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
this.sendDOMMessage(options);
return;
}
// options.provisioned informs about the called party receives the calling
// party's address information:
// 0 for CLIP not provisioned
// 1 for CLIP provisioned
// 2 for unknown
options.provisioned = Buf.readUint32();
if (options.rilMessageType === "sendMMI") {
switch (options.provisioned) {
case 0:
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
break;
case 1:
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
break;
default:
options.success = false;
options.errorMsg = MMI_ERROR_KS_ERROR;
break;
}
}
this.sendDOMMessage(options);
};
RIL[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
RIL.readDataCall_v5 = function readDataCall_v5(options) {
@ -5377,6 +5457,14 @@ RIL[REQUEST_VOICE_RADIO_TECH] = function REQUEST_VOICE_RADIO_TECH(length, option
let radioTech = Buf.readUint32List();
this._processRadioTech(radioTech[0]);
};
RIL[REQUEST_GET_UNLOCK_RETRY_COUNT] = function REQUEST_GET_UNLOCK_RETRY_COUNT(length, options) {
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
options.retryCount = length ? Buf.readUint32List()[0] : -1;
this.sendDOMMessage(options);
};
RIL[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
let radioState = Buf.readUint32();

View File

@ -0,0 +1,82 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
function run_test() {
run_next_test();
}
function _getWorker() {
let _postedMessage;
let _worker = newWorker({
postRILMessage: function fakePostRILMessage(data) {
},
postMessage: function fakePostMessage(message) {
_postedMessage = message;
}
});
return {
get postedMessage() {
return _postedMessage;
},
get worker() {
return _worker;
}
};
}
add_test(function test_queryCLIP_provisioned() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};
worker.RIL.queryCLIP = function fakeQueryCLIP(options) {
worker.Buf.int32Array = [
1, // CLIP provisioned.
1 // Length.
];
worker.RIL[REQUEST_QUERY_CLIP](1, {
rilRequestError: ERROR_SUCCESS
});
};
worker.RIL.queryCLIP({});
let postedMessage = workerHelper.postedMessage;
do_check_eq(postedMessage.errorMsg, undefined);
do_check_true(postedMessage.success);
do_check_eq(postedMessage.provisioned, 1);
run_next_test();
});
add_test(function test_getCLIP_error_generic_failure_invalid_length() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};
worker.RIL.queryCLIP = function fakeQueryCLIP(options) {
worker.Buf.int32Array = [
1, // CLIP provisioned.
0 // Length.
];
worker.RIL[REQUEST_QUERY_CLIP](1, {
rilRequestError: ERROR_SUCCESS
});
};
worker.RIL.queryCLIP({});
let postedMessage = workerHelper.postedMessage;
do_check_eq(postedMessage.errorMsg, "GenericFailure");
do_check_false(postedMessage.success);
run_next_test();
});

View File

@ -10,3 +10,4 @@ tail =
[test_ril_worker_cellbroadcast.js]
[test_ril_worker_ruim.js]
[test_ril_worker_cw.js]
[test_ril_worker_clip.js]