mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-23 23:57:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
374
ipc/netd/Netd.cpp
Normal file
374
ipc/netd/Netd.cpp
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "Netd.h"
|
||||
#include <android/log.h>
|
||||
#include <cutils/sockets.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "android/log.h"
|
||||
#include "base/task.h"
|
||||
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "SystemProperty.h"
|
||||
|
||||
#define NETD_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
|
||||
#define ICS_SYS_USB_RNDIS_MAC "/sys/class/android_usb/android0/f_rndis/ethaddr"
|
||||
#define INVALID_SOCKET -1
|
||||
#define MAX_RECONNECT_TIMES 10
|
||||
|
||||
using mozilla::system::Property;
|
||||
|
||||
namespace {
|
||||
|
||||
RefPtr<mozilla::ipc::NetdClient> gNetdClient;
|
||||
RefPtr<mozilla::ipc::NetdConsumer> gNetdConsumer;
|
||||
|
||||
class StopNetdConsumer : public mozilla::Runnable {
|
||||
public:
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
gNetdConsumer = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
InitRndisAddress()
|
||||
{
|
||||
char mac[20];
|
||||
char serialno[] = "1234567890ABCDEF";
|
||||
static const int kEthernetAddressLength = 6;
|
||||
char address[kEthernetAddressLength];
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int length = 0;
|
||||
mozilla::ScopedClose fd;
|
||||
|
||||
fd.rwget() = open(ICS_SYS_USB_RNDIS_MAC, O_WRONLY);
|
||||
if (fd.rwget() == -1) {
|
||||
NETD_LOG("Unable to open file %s.", ICS_SYS_USB_RNDIS_MAC);
|
||||
return false;
|
||||
}
|
||||
|
||||
Property::Get("ro.serialno", serialno, "1234567890ABCDEF");
|
||||
|
||||
memset(address, 0, sizeof(address));
|
||||
// First byte is 0x02 to signify a locally administered address.
|
||||
address[0] = 0x02;
|
||||
length = strlen(serialno);
|
||||
for (i = 0; i < length; i++) {
|
||||
address[i % (kEthernetAddressLength - 1) + 1] ^= serialno[i];
|
||||
}
|
||||
|
||||
SprintfLiteral(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
address[0], address[1], address[2],
|
||||
address[3], address[4], address[5]);
|
||||
length = strlen(mac);
|
||||
ret = write(fd.get(), mac, length);
|
||||
if (ret != length) {
|
||||
NETD_LOG("Fail to write file %s.", ICS_SYS_USB_RNDIS_MAC);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
NetdClient::NetdClient()
|
||||
: LineWatcher('\0', MAX_COMMAND_SIZE)
|
||||
, mIOLoop(MessageLoopForIO::current())
|
||||
, mSocket(INVALID_SOCKET)
|
||||
, mCurrentWriteOffset(0)
|
||||
, mReConnectTimes(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(NetdClient);
|
||||
}
|
||||
|
||||
NetdClient::~NetdClient()
|
||||
{
|
||||
MOZ_COUNT_DTOR(NetdClient);
|
||||
}
|
||||
|
||||
bool
|
||||
NetdClient::OpenSocket()
|
||||
{
|
||||
mSocket.rwget() = socket_local_client("netd",
|
||||
ANDROID_SOCKET_NAMESPACE_RESERVED,
|
||||
SOCK_STREAM);
|
||||
if (mSocket.rwget() < 0) {
|
||||
NETD_LOG("Error connecting to : netd (%s) - will retry", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
// Add FD_CLOEXEC flag.
|
||||
int flags = fcntl(mSocket.get(), F_GETFD);
|
||||
if (flags == -1) {
|
||||
NETD_LOG("Error doing fcntl with F_GETFD command(%s)", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
flags |= FD_CLOEXEC;
|
||||
if (fcntl(mSocket.get(), F_SETFD, flags) == -1) {
|
||||
NETD_LOG("Error doing fcntl with F_SETFD command(%s)", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
// Set non-blocking.
|
||||
if (fcntl(mSocket.get(), F_SETFL, O_NONBLOCK) == -1) {
|
||||
NETD_LOG("Error set non-blocking socket(%s)", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (!MessageLoopForIO::current()->
|
||||
WatchFileDescriptor(mSocket.get(),
|
||||
true,
|
||||
MessageLoopForIO::WATCH_READ,
|
||||
&mReadWatcher,
|
||||
this)) {
|
||||
NETD_LOG("Error set socket read watcher(%s)", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mOutgoingQ.empty()) {
|
||||
MessageLoopForIO::current()->
|
||||
WatchFileDescriptor(mSocket.get(),
|
||||
false,
|
||||
MessageLoopForIO::WATCH_WRITE,
|
||||
&mWriteWatcher,
|
||||
this);
|
||||
}
|
||||
|
||||
NETD_LOG("Connected to netd");
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetdClient::OnLineRead(int aFd, nsDependentCSubstring& aMessage)
|
||||
{
|
||||
// Set errno to 0 first. For preventing to use the stale version of errno.
|
||||
errno = 0;
|
||||
// We found a line terminator. Each line is formatted as an
|
||||
// integer response code followed by the rest of the line.
|
||||
// Fish out the response code.
|
||||
int responseCode = strtol(aMessage.Data(), nullptr, 10);
|
||||
if (!errno) {
|
||||
NetdCommand* response = new NetdCommand();
|
||||
// Passing all the response message, including the line terminator.
|
||||
response->mSize = aMessage.Length();
|
||||
memcpy(response->mData, aMessage.Data(), aMessage.Length());
|
||||
gNetdConsumer->MessageReceived(response);
|
||||
}
|
||||
|
||||
if (!responseCode) {
|
||||
NETD_LOG("Can't parse netd's response");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetdClient::OnFileCanWriteWithoutBlocking(int aFd)
|
||||
{
|
||||
MOZ_ASSERT(aFd == mSocket.get());
|
||||
WriteNetdCommand();
|
||||
}
|
||||
|
||||
void
|
||||
NetdClient::OnError()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
mReadWatcher.StopWatchingFileDescriptor();
|
||||
mWriteWatcher.StopWatchingFileDescriptor();
|
||||
|
||||
mSocket.dispose();
|
||||
mCurrentWriteOffset = 0;
|
||||
mCurrentNetdCommand = nullptr;
|
||||
while (!mOutgoingQ.empty()) {
|
||||
delete mOutgoingQ.front();
|
||||
mOutgoingQ.pop();
|
||||
}
|
||||
Start();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
NetdClient::Start()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
if (!gNetdClient) {
|
||||
NETD_LOG("Netd Client is not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gNetdClient->OpenSocket()) {
|
||||
// Socket open failed, try again in a second.
|
||||
NETD_LOG("Fail to connect to Netd");
|
||||
if (++gNetdClient->mReConnectTimes > MAX_RECONNECT_TIMES) {
|
||||
NETD_LOG("Fail to connect to Netd after retry %d times", MAX_RECONNECT_TIMES);
|
||||
return;
|
||||
}
|
||||
|
||||
MessageLoopForIO::current()->
|
||||
PostDelayedTask(NewRunnableFunction(NetdClient::Start),
|
||||
1000);
|
||||
return;
|
||||
}
|
||||
gNetdClient->mReConnectTimes = 0;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
NetdClient::SendNetdCommandIOThread(NetdCommand* aMessage)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(aMessage);
|
||||
|
||||
if (!gNetdClient) {
|
||||
NETD_LOG("Netd Client is not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
gNetdClient->mOutgoingQ.push(aMessage);
|
||||
|
||||
if (gNetdClient->mSocket.get() == INVALID_SOCKET) {
|
||||
NETD_LOG("Netd connection is not established, push the message to queue");
|
||||
return;
|
||||
}
|
||||
|
||||
gNetdClient->WriteNetdCommand();
|
||||
}
|
||||
|
||||
void
|
||||
NetdClient::WriteNetdCommand()
|
||||
{
|
||||
if (!mCurrentNetdCommand) {
|
||||
mCurrentWriteOffset = 0;
|
||||
mCurrentNetdCommand = mOutgoingQ.front();
|
||||
mOutgoingQ.pop();
|
||||
}
|
||||
|
||||
while (mCurrentWriteOffset < mCurrentNetdCommand->mSize) {
|
||||
ssize_t write_amount = mCurrentNetdCommand->mSize - mCurrentWriteOffset;
|
||||
ssize_t written = write(mSocket.get(),
|
||||
mCurrentNetdCommand->mData + mCurrentWriteOffset,
|
||||
write_amount);
|
||||
if (written < 0) {
|
||||
NETD_LOG("Cannot write to network, error %d\n", (int) written);
|
||||
OnError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (written > 0) {
|
||||
mCurrentWriteOffset += written;
|
||||
}
|
||||
|
||||
if (written != write_amount) {
|
||||
NETD_LOG("WriteNetdCommand fail !!! Write is not completed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mCurrentWriteOffset != mCurrentNetdCommand->mSize) {
|
||||
MessageLoopForIO::current()->
|
||||
WatchFileDescriptor(mSocket.get(),
|
||||
false,
|
||||
MessageLoopForIO::WATCH_WRITE,
|
||||
&mWriteWatcher,
|
||||
this);
|
||||
return;
|
||||
}
|
||||
|
||||
mCurrentNetdCommand = nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
InitNetdIOThread()
|
||||
{
|
||||
bool result;
|
||||
char propValue[Property::VALUE_MAX_LENGTH];
|
||||
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(!gNetdClient);
|
||||
|
||||
Property::Get("ro.build.version.sdk", propValue, "0");
|
||||
// Assign rndis address for usb tethering in ICS.
|
||||
if (atoi(propValue) >= 15) {
|
||||
result = InitRndisAddress();
|
||||
// We don't return here because InitRnsisAddress() function is related to
|
||||
// usb tethering only. Others service such as wifi tethering still need
|
||||
// to use ipc to communicate with netd.
|
||||
if (!result) {
|
||||
NETD_LOG("fail to give rndis interface an address");
|
||||
}
|
||||
}
|
||||
gNetdClient = new NetdClient();
|
||||
gNetdClient->Start();
|
||||
}
|
||||
|
||||
static void
|
||||
ShutdownNetdIOThread()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
nsCOMPtr<nsIRunnable> shutdownEvent = new StopNetdConsumer();
|
||||
|
||||
gNetdClient = nullptr;
|
||||
|
||||
NS_DispatchToMainThread(shutdownEvent);
|
||||
}
|
||||
|
||||
void
|
||||
StartNetd(NetdConsumer* aNetdConsumer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aNetdConsumer);
|
||||
MOZ_ASSERT(gNetdConsumer == nullptr);
|
||||
|
||||
gNetdConsumer = aNetdConsumer;
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
NewRunnableFunction(InitNetdIOThread));
|
||||
}
|
||||
|
||||
void
|
||||
StopNetd()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsIThread* currentThread = NS_GetCurrentThread();
|
||||
NS_ASSERTION(currentThread, "This should never be null!");
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
NewRunnableFunction(ShutdownNetdIOThread));
|
||||
|
||||
while (gNetdConsumer) {
|
||||
if (!NS_ProcessNextEvent(currentThread)) {
|
||||
NS_WARNING("Something bad happened!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* This function runs in net worker Thread context. The net worker thread
|
||||
* is created in dom/system/gonk/NetworkManager.js
|
||||
*
|
||||
**************************************************************************/
|
||||
void
|
||||
SendNetdCommand(NetdCommand* aMessage)
|
||||
{
|
||||
MOZ_ASSERT(aMessage);
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
NewRunnableFunction(NetdClient::SendNetdCommandIOThread, aMessage));
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
81
ipc/netd/Netd.h
Normal file
81
ipc/netd/Netd.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_system_netd_h__
|
||||
#define mozilla_system_netd_h__
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
|
||||
#define MAX_COMMAND_SIZE 4096
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
/*
|
||||
* Represents raw data going to or coming from the Netd socket.
|
||||
*/
|
||||
struct NetdCommand
|
||||
{
|
||||
uint8_t mData[MAX_COMMAND_SIZE];
|
||||
|
||||
// Number of octets in mData.
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
class NetdConsumer
|
||||
{
|
||||
protected:
|
||||
virtual ~NetdConsumer() { }
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(NetdConsumer)
|
||||
|
||||
virtual void MessageReceived(NetdCommand* aMessage) = 0;
|
||||
};
|
||||
|
||||
class NetdWriteTask : public Runnable
|
||||
{
|
||||
NS_IMETHOD Run();
|
||||
};
|
||||
|
||||
class NetdClient : public MessageLoopForIO::LineWatcher
|
||||
{
|
||||
virtual ~NetdClient();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(NetdClient)
|
||||
typedef std::queue<NetdCommand*> NetdCommandQueue;
|
||||
|
||||
NetdClient();
|
||||
static void Start();
|
||||
static void SendNetdCommandIOThread(NetdCommand* aMessage);
|
||||
|
||||
private:
|
||||
void WriteNetdCommand();
|
||||
virtual void OnError();
|
||||
virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage);
|
||||
virtual void OnFileCanWriteWithoutBlocking(int aFd);
|
||||
bool OpenSocket();
|
||||
|
||||
MessageLoopForIO *mIOLoop;
|
||||
MessageLoopForIO::FileDescriptorWatcher mReadWatcher;
|
||||
MessageLoopForIO::FileDescriptorWatcher mWriteWatcher;
|
||||
ScopedClose mSocket;
|
||||
NetdCommandQueue mOutgoingQ;
|
||||
nsAutoPtr<NetdCommand> mCurrentNetdCommand;
|
||||
size_t mCurrentWriteOffset;
|
||||
size_t mReConnectTimes;
|
||||
};
|
||||
|
||||
void StartNetd(NetdConsumer *);
|
||||
void StopNetd();
|
||||
void SendNetdCommand(NetdCommand *);
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_system_netd_h__
|
||||
17
ipc/netd/moz.build
Normal file
17
ipc/netd/moz.build
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
EXPORTS.mozilla.ipc += [
|
||||
'Netd.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'Netd.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
Loading…
Add table
Add a link
Reference in a new issue