mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-01 05:43:46 +00:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
36799dd75c
@ -65,14 +65,7 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
|
||||
|
||||
// =================== RIL ====================
|
||||
(function RILSettingsToPrefs() {
|
||||
['ril.data.enabled', 'ril.data.roaming.enabled'].forEach(function(key) {
|
||||
SettingsListener.observe(key, false, function(value) {
|
||||
Services.prefs.setBoolPref(key, value);
|
||||
});
|
||||
});
|
||||
|
||||
let strPrefs = ['ril.data.apn', 'ril.data.user', 'ril.data.passwd',
|
||||
'ril.data.mmsc', 'ril.data.mmsproxy'];
|
||||
let strPrefs = ['ril.data.mmsc', 'ril.data.mmsproxy'];
|
||||
strPrefs.forEach(function(key) {
|
||||
SettingsListener.observe(key, "", function(value) {
|
||||
Services.prefs.setCharPref(key, value);
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r160364"
|
||||
"clang_version": "r161022"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 65680370,
|
||||
"digest": "5d343ea80cb0ace0f2a1683466015679dfacd0ae5584a89f001710c6d665f9fbd757edef5b1bd440f234553f9dbad06c8d1eed74b71a3d11e04e7f4e2c929628",
|
||||
"size": 65670083,
|
||||
"digest": "681a8f14d9e44e4220ac69f8c545406a40962472ee8fb342b619e04e1a316ddc8802f29f39765cbc06603cc9d4774ac5c2e2d320bf3ec6bc0c7502a5abdd080e",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r160364"
|
||||
"clang_version": "r161022"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 61020656,
|
||||
"digest": "822dc6f076309b1e45ef0ea77f88b9f5b73c8f1d0bb9c52147a2f99c4bdb67272442c9e89ab88bdadc94e2dead5e5cafc5ccea8211f42919b5ff9242bf2844d5",
|
||||
"size": 61189616,
|
||||
"digest": "ec5d4787a11f5feff8ecfa2ec91f313cc7a6968ef419c74c25200ed7df92362d566142d405269ee2f0a14d291a834d39cd5dca826d819d6599426470e80bd2c8",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r160364"
|
||||
"clang_version": "r161022"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 54422251,
|
||||
"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
|
||||
"size": 54405078,
|
||||
"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r160364"
|
||||
"clang_version": "r161022"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 54422251,
|
||||
"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
|
||||
"size": 54405078,
|
||||
"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r160364"
|
||||
"clang_version": "r161022"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 54422251,
|
||||
"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
|
||||
"size": 54405078,
|
||||
"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"clang_version": "r160364"
|
||||
"clang_version": "r161022"
|
||||
},
|
||||
{
|
||||
"size": 47,
|
||||
@ -9,8 +9,8 @@
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 54422251,
|
||||
"digest": "8208645d24ac87975a091ff66a90c20589ff8945936ed9b16ca81976c59bf1166ed9f79709698d435480774fba8ed9f9f178dc189305c86162acac8fda19830e",
|
||||
"size": 54405078,
|
||||
"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2"
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
# 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/.
|
||||
|
||||
llvm_revision = "160364"
|
||||
llvm_revision = "161022"
|
||||
moz_version = "moz0"
|
||||
|
||||
##############################################
|
||||
@ -86,6 +86,8 @@ def build_one_stage_aux(stage_dir, is_stage_one):
|
||||
build_package(llvm_source_dir, build_dir, configure_opts)
|
||||
|
||||
isDarwin = platform.system() == "Darwin"
|
||||
if isDarwin:
|
||||
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
|
||||
|
||||
if not os.path.exists(source_dir):
|
||||
os.makedirs(source_dir)
|
||||
|
@ -23,6 +23,8 @@ const TOPIC_INTERFACE_REGISTERED = "network-interface-registered";
|
||||
const TOPIC_INTERFACE_UNREGISTERED = "network-interface-unregistered";
|
||||
const TOPIC_DEFAULT_ROUTE_CHANGED = "network-default-route-changed";
|
||||
|
||||
const MANUAL_PROXY_CONFIGURATION = 1;
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
/**
|
||||
@ -188,8 +190,35 @@ NetworkManager.prototype = {
|
||||
oldIfname: (oldInterface && oldInterface != this.active) ? oldInterface.name : null
|
||||
};
|
||||
this.worker.postMessage(options);
|
||||
this.setNetworkProxy();
|
||||
},
|
||||
|
||||
setNetworkProxy: function setNetworkProxy() {
|
||||
try {
|
||||
if (!this.active.httpProxyHost || this.active.httpProxyHost == "") {
|
||||
// Sets direct connection to internet.
|
||||
Services.prefs.clearUserPref("network.proxy.type");
|
||||
Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
|
||||
Services.prefs.clearUserPref("network.proxy.http");
|
||||
Services.prefs.clearUserPref("network.proxy.http_port");
|
||||
debug("No proxy support for " + this.active.name + " network interface.");
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Going to set proxy settings for " + this.active.name + " network interface.");
|
||||
// Sets manual proxy configuration.
|
||||
Services.prefs.setIntPref("network.proxy.type", MANUAL_PROXY_CONFIGURATION);
|
||||
// Do not use this proxy server for all protocols.
|
||||
Services.prefs.setBoolPref("network.proxy.share_proxy_settings", false);
|
||||
Services.prefs.setCharPref("network.proxy.http", this.active.httpProxyHost);
|
||||
let port = this.active.httpProxyPort == "" ? 8080 : this.active.httpProxyPort;
|
||||
Services.prefs.setIntPref("network.proxy.http_port", port);
|
||||
} catch (ex) {
|
||||
debug("Exception " + ex + ". Unable to set proxy setting for "
|
||||
+ this.active.name + " network interface.");
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkManager]);
|
||||
|
@ -175,6 +175,22 @@ function RadioInterfaceLayer() {
|
||||
// value at boot time.
|
||||
gSettingsService.getLock().get("ril.radio.disabled", this);
|
||||
|
||||
// Read the APN data form the setting DB.
|
||||
gSettingsService.getLock().get("ril.data.apn", this);
|
||||
gSettingsService.getLock().get("ril.data.user", this);
|
||||
gSettingsService.getLock().get("ril.data.passwd", this);
|
||||
gSettingsService.getLock().get("ril.data.httpProxyHost", this);
|
||||
gSettingsService.getLock().get("ril.data.httpProxyPort", this);
|
||||
gSettingsService.getLock().get("ril.data.roaming_enabled", this);
|
||||
gSettingsService.getLock().get("ril.data.enabled", this);
|
||||
this._dataCallSettingsToRead = ["ril.data.enabled",
|
||||
"ril.data.roaming_enabled",
|
||||
"ril.data.apn",
|
||||
"ril.data.user",
|
||||
"ril.data.passwd",
|
||||
"ril.data.httpProxyHost",
|
||||
"ril.data.httpProxyPort"];
|
||||
|
||||
for each (let msgname in RIL_IPC_MSG_NAMES) {
|
||||
ppmm.addMessageListener(msgname, this);
|
||||
}
|
||||
@ -332,7 +348,7 @@ RadioInterfaceLayer.prototype = {
|
||||
case "datacallerror":
|
||||
// 3G Network revoked the data connection, possible unavailable APN
|
||||
debug("Received data registration error message. Failed APN " +
|
||||
Services.prefs.getCharPref("ril.data.apn"));
|
||||
this.dataCallSettings["apn"]);
|
||||
RILNetworkInterface.reset();
|
||||
break;
|
||||
case "signalstrengthchange":
|
||||
@ -516,22 +532,6 @@ RadioInterfaceLayer.prototype = {
|
||||
return false;
|
||||
},
|
||||
|
||||
_isDataEnabled: function _isDataEnabled() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref("ril.data.enabled");
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
_isDataRoamingEnabled: function _isDataRoamingEnabled() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref("ril.data.roaming.enabled");
|
||||
} catch(ex) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
updateDataConnection: function updateDataConnection(state) {
|
||||
let data = this.rilContext.data;
|
||||
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
|
||||
@ -550,21 +550,20 @@ RadioInterfaceLayer.prototype = {
|
||||
data.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
|
||||
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
|
||||
|
||||
if (!this._isDataEnabled()) {
|
||||
if (!this.dataCallSettings["enabled"]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let isRegistered =
|
||||
state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME ||
|
||||
(this._isDataRoamingEnabled() &&
|
||||
(this.dataCallSettings["roaming_enabled"] &&
|
||||
state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
|
||||
let haveDataConnection =
|
||||
state.radioTech != RIL.NETWORK_CREG_TECH_UNKNOWN;
|
||||
|
||||
if (isRegistered && haveDataConnection) {
|
||||
debug("Radio is ready for data connection.");
|
||||
// RILNetworkInterface will ignore this if it's already connected.
|
||||
RILNetworkInterface.connect();
|
||||
this.updateRILNetworkInterface();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@ -638,6 +637,39 @@ RadioInterfaceLayer.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
updateRILNetworkInterface: function updateRILNetworkInterface() {
|
||||
if (this._dataCallSettingsToRead.length) {
|
||||
debug("We haven't read completely the APN data from the " +
|
||||
"settings DB yet. Wait for that.");
|
||||
return;
|
||||
}
|
||||
|
||||
// This check avoids data call connection if the radio is not ready
|
||||
// yet after toggling off airplane mode.
|
||||
if (this.rilContext.radioState != RIL.GECKO_RADIOSTATE_READY) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We only watch at "ril.data.enabled" flag changes for connecting or
|
||||
// disconnecting the data call. If the value of "ril.data.enabled" is
|
||||
// true and any of the remaining flags change the setting application
|
||||
// should turn this flag to false and then to true in order to reload
|
||||
// the new values and reconnect the data call.
|
||||
if (this._oldRilDataEnabledState == this.dataCallSettings["enabled"]) {
|
||||
debug("No changes for ril.data.enabled flag. Nothing to do.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.dataCallSettings["enabled"] && RILNetworkInterface.connected) {
|
||||
debug("Data call settings: disconnect data call.");
|
||||
RILNetworkInterface.disconnect();
|
||||
}
|
||||
if (this.dataCallSettings["enabled"] && !RILNetworkInterface.connected) {
|
||||
debug("Data call settings connect data call.");
|
||||
RILNetworkInterface.connect(this.dataCallSettings);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Track the active call and update the audio system as its state changes.
|
||||
*/
|
||||
@ -924,33 +956,6 @@ RadioInterfaceLayer.prototype = {
|
||||
[message.datacalls, message.datacalls.length]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle setting changes.
|
||||
*/
|
||||
handleMozSettingsChanged: function handleMozSettingsChanged(setting) {
|
||||
switch (setting.key) {
|
||||
case "ril.radio.disabled":
|
||||
this._radioEnabled = !setting.value;
|
||||
this._ensureRadioState();
|
||||
break;
|
||||
case "ril.data.enabled":
|
||||
// We only watch at "ril.data.enabled" flag changes for connecting or
|
||||
// disconnecting the data call. If the value of "ril.data.enabled" is
|
||||
// true and any of the remaining flags change the setting application
|
||||
// should turn this flag to false and then to true in order to reload
|
||||
// the new values and reconnect the data call.
|
||||
if (!setting.value && RILNetworkInterface.connected) {
|
||||
debug("Data call settings: disconnect data call.");
|
||||
RILNetworkInterface.disconnect();
|
||||
}
|
||||
if (setting.value && !RILNetworkInterface.connected) {
|
||||
debug("Data call settings connect data call.");
|
||||
RILNetworkInterface.connect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleICCGetCardLock: function handleICCGetCardLock(message) {
|
||||
ppmm.sendAsyncMessage("RIL:GetCardLock:Return:OK", message);
|
||||
},
|
||||
@ -988,7 +993,7 @@ RadioInterfaceLayer.prototype = {
|
||||
switch (topic) {
|
||||
case kMozSettingsChangedObserverTopic:
|
||||
let setting = JSON.parse(data);
|
||||
this.handleMozSettingsChanged(setting);
|
||||
this.handle(setting.key, setting.value);
|
||||
break;
|
||||
case "xpcom-shutdown":
|
||||
for each (let msgname in RIL_IPC_MSG_NAMES) {
|
||||
@ -1008,19 +1013,49 @@ RadioInterfaceLayer.prototype = {
|
||||
// corresponds to the 'ril.radio.disabled' setting from the UI.
|
||||
_radioEnabled: null,
|
||||
|
||||
// APN data for making data calls.
|
||||
dataCallSettings: {},
|
||||
_dataCallSettingsToRead: [],
|
||||
_oldRilDataEnabledState: null,
|
||||
|
||||
handle: function handle(aName, aResult) {
|
||||
if (aName == "ril.radio.disabled") {
|
||||
debug("'ril.radio.disabled' is " + aResult);
|
||||
this._radioEnabled = !aResult;
|
||||
this._ensureRadioState();
|
||||
}
|
||||
switch(aName) {
|
||||
case "ril.radio.disabled":
|
||||
debug("'ril.radio.disabled' is now " + aResult);
|
||||
this._radioEnabled = !aResult;
|
||||
this._ensureRadioState();
|
||||
break;
|
||||
case "ril.data.enabled":
|
||||
this._oldRilDataEnabledState = this.dataCallSettings["enabled"];
|
||||
// Fall through!
|
||||
case "ril.data.roaming_enabled":
|
||||
case "ril.data.apn":
|
||||
case "ril.data.user":
|
||||
case "ril.data.passwd":
|
||||
case "ril.data.httpProxyHost":
|
||||
case "ril.data.httpProxyPort":
|
||||
let key = aName.slice(9);
|
||||
this.dataCallSettings[key] = aResult;
|
||||
debug("'" + aName + "'" + " is now " + this.dataCallSettings[key]);
|
||||
let index = this._dataCallSettingsToRead.indexOf(aName);
|
||||
if (index != -1) {
|
||||
this._dataCallSettingsToRead.splice(index, 1);
|
||||
}
|
||||
this.updateRILNetworkInterface();
|
||||
break;
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
handleError: function handleError(aErrorMessage) {
|
||||
debug("There was an error reading the 'ril.radio.disabled' setting., " +
|
||||
"default to radio on.");
|
||||
debug("There was an error while reading RIL settings.");
|
||||
|
||||
// Default radio to on.
|
||||
this._radioEnabled = true;
|
||||
this._ensureRadioState();
|
||||
|
||||
// Clean data call setting.
|
||||
this.dataCallSettings = {};
|
||||
this.dataCallSettings["enabled"] = false;
|
||||
},
|
||||
|
||||
// nsIRadioWorker
|
||||
@ -1728,6 +1763,10 @@ let RILNetworkInterface = {
|
||||
|
||||
dhcp: false,
|
||||
|
||||
httpProxyHost: null,
|
||||
|
||||
httpProxyPort: null,
|
||||
|
||||
// nsIRILDataCallback
|
||||
|
||||
dataCallStateChanged: function dataCallStateChanged(datacall) {
|
||||
@ -1767,6 +1806,7 @@ let RILNetworkInterface = {
|
||||
registeredAsDataCallCallback: false,
|
||||
registeredAsNetworkInterface: false,
|
||||
connecting: false,
|
||||
dataCallSettings: {},
|
||||
|
||||
// APN failed connections. Retry counter
|
||||
apnRetryCounter: 0,
|
||||
@ -1782,31 +1822,31 @@ let RILNetworkInterface = {
|
||||
return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED;
|
||||
},
|
||||
|
||||
connect: function connect() {
|
||||
connect: function connect(options) {
|
||||
if (this.connecting ||
|
||||
this.state == RIL.GECKO_NETWORK_STATE_CONNECTED ||
|
||||
this.state == RIL.GECKO_NETWORK_STATE_SUSPENDED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.registeredAsDataCallCallback) {
|
||||
this.mRIL.registerDataCallCallback(this);
|
||||
this.registeredAsDataCallCallback = true;
|
||||
}
|
||||
|
||||
let apn, user, passwd;
|
||||
// Eventually these values would be retrieved from the user's preferences
|
||||
// via the settings API. For now we just use Gecko's preferences.
|
||||
try {
|
||||
apn = Services.prefs.getCharPref("ril.data.apn");
|
||||
user = Services.prefs.getCharPref("ril.data.user");
|
||||
passwd = Services.prefs.getCharPref("ril.data.passwd");
|
||||
} catch (ex) {
|
||||
debug("No APN settings found, not going to set up data connection.");
|
||||
return;
|
||||
if (options) {
|
||||
// Save the APN data locally for using them in connection retries.
|
||||
this.dataCallSettings = options;
|
||||
}
|
||||
debug("Going to set up data connection with APN " + apn);
|
||||
|
||||
this.httpProxyHost = this.dataCallSettings["httpProxyHost"];
|
||||
this.httpProxyPort = this.dataCallSettings["httpProxyPort"];
|
||||
|
||||
debug("Going to set up data connection with APN " + this.dataCallSettings["apn"]);
|
||||
this.mRIL.setupDataCall(RIL.DATACALL_RADIOTECHNOLOGY_GSM,
|
||||
apn, user, passwd,
|
||||
this.dataCallSettings["apn"],
|
||||
this.dataCallSettings["user"],
|
||||
this.dataCallSettings["passwd"],
|
||||
RIL.DATACALL_AUTH_PAP_OR_CHAP, "IP");
|
||||
this.connecting = true;
|
||||
},
|
||||
|
@ -7,7 +7,7 @@
|
||||
/**
|
||||
* Information about networks that is exposed to network manager API consumers.
|
||||
*/
|
||||
[scriptable, uuid(e016d594-3072-11e1-9b7d-0010183a41af)]
|
||||
[scriptable, uuid(57b56c6f-4c3f-4c55-bf1b-e5af22407931)]
|
||||
interface nsINetworkInterface : nsISupports
|
||||
{
|
||||
const long NETWORK_STATE_UNKNOWN = -1;
|
||||
@ -44,6 +44,16 @@ interface nsINetworkInterface : nsISupports
|
||||
*/
|
||||
readonly attribute boolean dhcp;
|
||||
|
||||
/**
|
||||
* The host name of the http proxy server.
|
||||
*/
|
||||
readonly attribute DOMString httpProxyHost;
|
||||
|
||||
/*
|
||||
* The port number of the http proxy server.
|
||||
*/
|
||||
readonly attribute long httpProxyPort;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1267,6 +1267,10 @@ let WifiNetworkInterface = {
|
||||
// to the Network Manager.
|
||||
dhcp: false,
|
||||
|
||||
httpProxyHost: null,
|
||||
|
||||
httpProxyPort: null,
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -15,12 +15,15 @@
|
||||
*/
|
||||
|
||||
#include <android/log.h>
|
||||
#include <fcntl.h>
|
||||
#include <sysutils/NetlinkEvent.h>
|
||||
|
||||
#include "base/message_loop.h"
|
||||
|
||||
#include "Hal.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "UeventPoller.h"
|
||||
|
||||
@ -28,31 +31,170 @@ using namespace mozilla::hal;
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GonkSwitch" , ## args)
|
||||
|
||||
#define SWITCH_HEADSET_DEVPATH "/devices/virtual/switch/h2w"
|
||||
#define SWITCH_USB_DEVPATH_GB "/devices/virtual/switch/usb_configuration"
|
||||
#define SWITCH_USB_DEVPATH_ICS "/devices/virtual/android_usb/android0"
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
/**
|
||||
* The uevent for a headset on SGS2 insertion looks like:
|
||||
*
|
||||
* change@/devices/virtual/switch/h2w
|
||||
* ACTION=change
|
||||
* DEVPATH=/devices/virtual/switch/h2w
|
||||
* SUBSYSTEM=switch
|
||||
* SWITCH_NAME=h2w
|
||||
* SWITCH_STATE=2
|
||||
* SEQNUM=2581
|
||||
* On Otoro, SWITCH_NAME could be Headset/No Device when plug/unplug.
|
||||
* change@/devices/virtual/switch/h2w
|
||||
* ACTION=change
|
||||
* DEVPATH=/devices/virtual/switch/h2w
|
||||
* SUBSYSTEM=switch
|
||||
* SWITCH_NAME=Headset
|
||||
* SWITCH_STATE=1
|
||||
* SEQNUM=1602
|
||||
*
|
||||
* The uevent for usb on GB,
|
||||
* change@/devices/virtual/switch/usb_configuration
|
||||
* ACTION=change
|
||||
* DEVPATH=/devices/virtual/switch/usb_configuration
|
||||
* SUBSYSTEM=switch
|
||||
* SWITCH_NAME=usb_configuration
|
||||
* SWITCH_STATE=0
|
||||
* SEQNUM=5038
|
||||
*/
|
||||
class SwitchHandler : public RefCounted<SwitchHandler>
|
||||
{
|
||||
public:
|
||||
SwitchHandler(const char* aDevPath, SwitchDevice aDevice)
|
||||
: mDevPath(aDevPath),
|
||||
mState(SWITCH_STATE_UNKNOWN),
|
||||
mDevice(aDevice)
|
||||
{
|
||||
GetInitialState();
|
||||
}
|
||||
|
||||
struct {const char* name; SwitchDevice device; } kSwitchNameMap[] = {
|
||||
{ "h2w", SWITCH_HEADPHONES },
|
||||
{ "usb_configuration", SWITCH_USB },
|
||||
{ NULL, SWITCH_DEVICE_UNKNOWN },
|
||||
virtual ~SwitchHandler()
|
||||
{
|
||||
}
|
||||
|
||||
bool CheckEvent(NetlinkEvent* aEvent)
|
||||
{
|
||||
if (strcmp(GetSubsystem(), aEvent->getSubsystem()) ||
|
||||
strcmp(mDevPath, aEvent->findParam("DEVPATH"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mState = ConvertState(GetStateString(aEvent));
|
||||
return mState != SWITCH_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
SwitchState GetState()
|
||||
{
|
||||
return mState;
|
||||
}
|
||||
|
||||
SwitchDevice GetType()
|
||||
{
|
||||
return mDevice;
|
||||
}
|
||||
protected:
|
||||
virtual const char* GetSubsystem()
|
||||
{
|
||||
return "switch";
|
||||
}
|
||||
|
||||
virtual const char* GetStateString(NetlinkEvent* aEvent)
|
||||
{
|
||||
return aEvent->findParam("SWITCH_STATE");
|
||||
}
|
||||
|
||||
void GetInitialState()
|
||||
{
|
||||
nsPrintfCString statePath("/sys%s/state", mDevPath);
|
||||
int fd = open(statePath.get(), O_RDONLY);
|
||||
if (fd <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedClose autoClose(fd);
|
||||
char state[16];
|
||||
ssize_t bytesRead = read(fd, state, sizeof(state));
|
||||
if (bytesRead < 0) {
|
||||
LOG("Read data from %s fails", statePath.get());
|
||||
return;
|
||||
}
|
||||
|
||||
if (state[bytesRead - 1] == '\n') {
|
||||
bytesRead--;
|
||||
}
|
||||
|
||||
state[bytesRead] = '\0';
|
||||
mState = ConvertState(state);
|
||||
}
|
||||
|
||||
virtual SwitchState ConvertState(const char* aState)
|
||||
{
|
||||
MOZ_ASSERT(aState);
|
||||
return aState[0] == '0' ? SWITCH_STATE_OFF : SWITCH_STATE_ON;
|
||||
}
|
||||
|
||||
const char* mDevPath;
|
||||
SwitchState mState;
|
||||
SwitchDevice mDevice;
|
||||
};
|
||||
|
||||
static SwitchDevice
|
||||
NameToDevice(const char* name) {
|
||||
for (int i = 0; kSwitchNameMap[i].device != SWITCH_DEVICE_UNKNOWN; i++) {
|
||||
if (strcmp(name, kSwitchNameMap[i].name) == 0) {
|
||||
return kSwitchNameMap[i].device;
|
||||
}
|
||||
/**
|
||||
* The uevent delivered for the USB configuration under ICS looks like,
|
||||
*
|
||||
* change@/devices/virtual/android_usb/android0
|
||||
* ACTION=change
|
||||
* DEVPATH=/devices/virtual/android_usb/android0
|
||||
* SUBSYSTEM=android_usb
|
||||
* USB_STATE=CONFIGURED
|
||||
* SEQNUM=1802
|
||||
*/
|
||||
class SwitchHandlerUsbIcs: public SwitchHandler
|
||||
{
|
||||
public:
|
||||
SwitchHandlerUsbIcs(const char* aDevPath) : SwitchHandler(aDevPath, SWITCH_USB)
|
||||
{
|
||||
SwitchHandler::GetInitialState();
|
||||
}
|
||||
return SWITCH_DEVICE_UNKNOWN;
|
||||
}
|
||||
|
||||
virtual ~SwitchHandlerUsbIcs() { }
|
||||
|
||||
protected:
|
||||
virtual const char* GetSubsystem()
|
||||
{
|
||||
return "android_usb";
|
||||
}
|
||||
|
||||
virtual const char* GetStateString(NetlinkEvent* aEvent)
|
||||
{
|
||||
return aEvent->findParam("USB_STATE");
|
||||
}
|
||||
|
||||
SwitchState ConvertState(const char* aState)
|
||||
{
|
||||
MOZ_ASSERT(aState);
|
||||
return strcmp(aState, "CONFIGURED") == 0 ? SWITCH_STATE_ON : SWITCH_STATE_OFF;
|
||||
}
|
||||
};
|
||||
|
||||
typedef nsTArray<RefPtr<SwitchHandler> > SwitchHandlerArray;
|
||||
|
||||
class SwitchEventRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
SwitchEventRunnable(SwitchEvent& event) : mEvent(event) {}
|
||||
SwitchEventRunnable(SwitchEvent& aEvent) : mEvent(aEvent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NotifySwitchChange(mEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -60,109 +202,124 @@ private:
|
||||
SwitchEvent mEvent;
|
||||
};
|
||||
|
||||
class SwitchEventObserver : public IUeventObserver
|
||||
class SwitchEventObserver : public IUeventObserver,
|
||||
public RefCounted<SwitchEventObserver>
|
||||
{
|
||||
public:
|
||||
SwitchEventObserver() : mEnableNum(0) {
|
||||
InternalInit();
|
||||
}
|
||||
~SwitchEventObserver() {}
|
||||
|
||||
int GetEnableCount() {
|
||||
return mEnableNum;
|
||||
SwitchEventObserver() : mEnableCount(0)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void EnableSwitch(SwitchDevice aDevice) {
|
||||
mEventInfo[aDevice].mEnable = true;
|
||||
mEnableNum++;
|
||||
~SwitchEventObserver()
|
||||
{
|
||||
mHandler.Clear();
|
||||
}
|
||||
|
||||
void DisableSwitch(SwitchDevice aDevice) {
|
||||
mEventInfo[aDevice].mEnable = false;
|
||||
mEnableNum--;
|
||||
int GetEnableCount()
|
||||
{
|
||||
return mEnableCount;
|
||||
}
|
||||
|
||||
void Notify(const NetlinkEvent& event) {
|
||||
const char* name;
|
||||
const char* state;
|
||||
|
||||
SwitchDevice device = ProcessEvent(event, &name, &state);
|
||||
if (device == SWITCH_DEVICE_UNKNOWN) {
|
||||
void EnableSwitch(SwitchDevice aDevice)
|
||||
{
|
||||
mEventInfo[aDevice].mEnabled = true;
|
||||
mEnableCount++;
|
||||
}
|
||||
|
||||
void DisableSwitch(SwitchDevice aDevice)
|
||||
{
|
||||
mEventInfo[aDevice].mEnabled = false;
|
||||
mEnableCount--;
|
||||
}
|
||||
|
||||
void Notify(const NetlinkEvent& aEvent)
|
||||
{
|
||||
SwitchState currState;
|
||||
|
||||
SwitchDevice device = GetEventInfo(aEvent, currState);
|
||||
if (device == SWITCH_DEVICE_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EventInfo& info = mEventInfo[device];
|
||||
info.mEvent.status() = atoi(state) == 0 ? SWITCH_STATE_OFF : SWITCH_STATE_ON;
|
||||
if (info.mEnable) {
|
||||
NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
|
||||
}
|
||||
EventInfo& info = mEventInfo[device];
|
||||
if (currState == info.mEvent.status()) {
|
||||
return;
|
||||
}
|
||||
|
||||
info.mEvent.status() = currState;
|
||||
|
||||
if (info.mEnabled) {
|
||||
NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
|
||||
}
|
||||
}
|
||||
|
||||
SwitchState GetCurrentInformation(SwitchDevice aDevice) {
|
||||
SwitchState GetCurrentInformation(SwitchDevice aDevice)
|
||||
{
|
||||
return mEventInfo[aDevice].mEvent.status();
|
||||
}
|
||||
|
||||
void NotifyAnEvent(SwitchDevice aDevice)
|
||||
{
|
||||
EventInfo& info = mEventInfo[aDevice];
|
||||
if (info.mEvent.status() != SWITCH_STATE_UNKNOWN) {
|
||||
NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent));
|
||||
}
|
||||
}
|
||||
private:
|
||||
class EventInfo {
|
||||
class EventInfo
|
||||
{
|
||||
public:
|
||||
EventInfo() : mEnable(false) {}
|
||||
EventInfo() : mEnabled(false)
|
||||
{
|
||||
mEvent.status() = SWITCH_STATE_UNKNOWN;
|
||||
mEvent.device() = SWITCH_DEVICE_UNKNOWN;
|
||||
}
|
||||
SwitchEvent mEvent;
|
||||
bool mEnable;
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
EventInfo mEventInfo[NUM_SWITCH_DEVICE];
|
||||
size_t mEnableNum;
|
||||
size_t mEnableCount;
|
||||
SwitchHandlerArray mHandler;
|
||||
|
||||
void InternalInit() {
|
||||
for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
|
||||
mEventInfo[i].mEvent.device() = kSwitchNameMap[i].device;
|
||||
mEventInfo[i].mEvent.status() = SWITCH_STATE_UNKNOWN;
|
||||
void Init()
|
||||
{
|
||||
mHandler.AppendElement(new SwitchHandler(SWITCH_HEADSET_DEVPATH, SWITCH_HEADPHONES));
|
||||
mHandler.AppendElement(new SwitchHandler(SWITCH_USB_DEVPATH_GB, SWITCH_USB));
|
||||
mHandler.AppendElement(new SwitchHandlerUsbIcs(SWITCH_USB_DEVPATH_ICS));
|
||||
|
||||
SwitchHandlerArray::index_type handlerIndex;
|
||||
SwitchHandlerArray::size_type numHandlers = mHandler.Length();
|
||||
|
||||
for (handlerIndex = 0; handlerIndex < numHandlers; handlerIndex++) {
|
||||
SwitchState state = mHandler[handlerIndex]->GetState();
|
||||
if (state == SWITCH_STATE_UNKNOWN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SwitchDevice device = mHandler[handlerIndex]->GetType();
|
||||
mEventInfo[device].mEvent.device() = device;
|
||||
mEventInfo[device].mEvent.status() = state;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetEventInfo(const NetlinkEvent& event, const char** name, const char** state) {
|
||||
SwitchDevice GetEventInfo(const NetlinkEvent& aEvent, SwitchState& aState)
|
||||
{
|
||||
//working around the android code not being const-correct
|
||||
NetlinkEvent *e = const_cast<NetlinkEvent*>(&event);
|
||||
const char* subsystem = e->getSubsystem();
|
||||
|
||||
if (subsystem && (strcmp(subsystem, "android_usb") == 0)) {
|
||||
// Under GB, usb cable plugin was done using a virtual switch
|
||||
// (usb_configuration). Under ICS, they changed to using the
|
||||
// android_usb device, so we emulate the usb_configuration switch.
|
||||
|
||||
*name = "usb_configuration";
|
||||
const char *usb_state = e->findParam("USB_STATE");
|
||||
if (!usb_state) {
|
||||
return false;
|
||||
NetlinkEvent *e = const_cast<NetlinkEvent*>(&aEvent);
|
||||
|
||||
for (size_t i = 0; i < mHandler.Length(); i++) {
|
||||
if (mHandler[i]->CheckEvent(e)) {
|
||||
aState = mHandler[i]->GetState();
|
||||
return mHandler[i]->GetType();
|
||||
}
|
||||
if (strcmp(usb_state, "CONFIGURED") == 0) {
|
||||
*state = "1";
|
||||
return true;
|
||||
}
|
||||
*state = "0";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!subsystem || strcmp(subsystem, "switch")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*name = e->findParam("SWITCH_NAME");
|
||||
*state = e->findParam("SWITCH_STATE");
|
||||
|
||||
if (!*name || !*state) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SwitchDevice ProcessEvent(const NetlinkEvent& event, const char** name, const char** state) {
|
||||
return GetEventInfo(event, name, state) ?
|
||||
NameToDevice(*name) : SWITCH_DEVICE_UNKNOWN;
|
||||
return SWITCH_DEVICE_UNKNOWN;
|
||||
}
|
||||
};
|
||||
|
||||
SwitchEventObserver* sSwitchObserver;
|
||||
static RefPtr<SwitchEventObserver> sSwitchObserver;
|
||||
|
||||
static void
|
||||
InitializeResourceIfNeed()
|
||||
@ -178,7 +335,6 @@ ReleaseResourceIfNeed()
|
||||
{
|
||||
if (sSwitchObserver->GetEnableCount() == 0) {
|
||||
UnregisterUeventListener(sSwitchObserver);
|
||||
delete sSwitchObserver;
|
||||
sSwitchObserver = NULL;
|
||||
}
|
||||
}
|
||||
@ -192,6 +348,11 @@ EnableSwitchNotificationsIOThread(SwitchDevice aDevice, Monitor *aMonitor)
|
||||
MonitorAutoLock lock(*aMonitor);
|
||||
lock.Notify();
|
||||
}
|
||||
|
||||
// Notify the latest state if IO thread has the information.
|
||||
if (sSwitchObserver->GetEnableCount() > 1) {
|
||||
sSwitchObserver->NotifyAnEvent(aDevice);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -19,6 +19,9 @@ class nsCocoaWindow;
|
||||
class nsChildView;
|
||||
class nsMenuBarX;
|
||||
|
||||
// Value copied from BITMAP_MAX_AREA, used in nsNativeThemeCocoa.mm
|
||||
#define CUIDRAW_MAX_AREA 500000
|
||||
|
||||
// If we are using an SDK older than 10.7, define bits we need that are missing
|
||||
// from it.
|
||||
#if !defined(MAC_OS_X_VERSION_10_7) || \
|
||||
|
@ -2759,6 +2759,9 @@ static void
|
||||
DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
|
||||
float aToolbarHeight, BOOL aIsMain)
|
||||
{
|
||||
if (aTitlebarRect.size.width * aTitlebarRect.size.height > CUIDRAW_MAX_AREA) {
|
||||
return;
|
||||
}
|
||||
int unifiedHeight = aTitlebarRect.size.height + aToolbarHeight;
|
||||
CUIDraw([NSWindow coreUIRenderer], aTitlebarRect, aContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
|
@ -1594,6 +1594,9 @@ nsNativeThemeCocoa::DrawSegment(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
nsIFrame* left = GetAdjacentSiblingFrameWithSameAppearance(aFrame, isRTL);
|
||||
nsIFrame* right = GetAdjacentSiblingFrameWithSameAppearance(aFrame, !isRTL);
|
||||
CGRect drawRect = SeparatorAdjustedRect(inBoxRect, left, aFrame, right);
|
||||
if (drawRect.size.width * drawRect.size.height > CUIDRAW_MAX_AREA) {
|
||||
return;
|
||||
}
|
||||
BOOL drawLeftSeparator = SeparatorResponsibility(left, aFrame) == aFrame;
|
||||
BOOL drawRightSeparator = SeparatorResponsibility(aFrame, right) == aFrame;
|
||||
NSControlSize controlSize = FindControlSize(drawRect.size.height, aSettings.heights, 4.0f);
|
||||
@ -1792,16 +1795,18 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB
|
||||
CGContextClipToRect(cgContext, inBoxRect);
|
||||
|
||||
CGRect drawRect = CGRectOffset(inBoxRect, 0, -titlebarHeight);
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(isMain ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithInt:unifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) {
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(isMain ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithInt:unifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
}
|
||||
|
||||
CGContextRestoreGState(cgContext);
|
||||
|
||||
@ -1827,16 +1832,18 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec
|
||||
const int extendUpwards = 40;
|
||||
drawRect.origin.y -= extendUpwards;
|
||||
drawRect.size.height += extendUpwards;
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(IsActive(aFrame, YES) ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithInt:inBoxRect.size.height], @"kCUIWindowFrameBottomBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawBottomBarSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) {
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(IsActive(aFrame, YES) ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithInt:inBoxRect.size.height], @"kCUIWindowFrameBottomBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawBottomBarSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
}
|
||||
|
||||
CGContextRestoreGState(cgContext);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user