mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 23:37:33 +09:00
parent
5830ff1f2b
commit
74df182488
232 changed files with 256 additions and 36730 deletions
|
|
@ -1,251 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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 <android/log.h>
|
||||
#include <cutils/android_reboot.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "automounter_gonk.h"
|
||||
#include "updatedefines.h"
|
||||
#include "updatelogging.h"
|
||||
|
||||
#define LOG_TAG "GonkAutoMounter"
|
||||
|
||||
#define GONK_LOG(level, format, ...) \
|
||||
LOG((LOG_TAG ": " format "\n", ##__VA_ARGS__)); \
|
||||
__android_log_print(level, LOG_TAG, format, ##__VA_ARGS__)
|
||||
|
||||
#define LOGI(format, ...) GONK_LOG(ANDROID_LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define LOGE(format, ...) GONK_LOG(ANDROID_LOG_ERROR, format, ##__VA_ARGS__)
|
||||
|
||||
const char *kGonkMountsPath = "/proc/mounts";
|
||||
const char *kGonkSystemPath = "/system";
|
||||
|
||||
GonkAutoMounter::GonkAutoMounter() : mDevice(nullptr), mAccess(Unknown)
|
||||
{
|
||||
if (!RemountSystem(ReadWrite)) {
|
||||
LOGE("Could not remount %s as read-write.", kGonkSystemPath);
|
||||
}
|
||||
}
|
||||
|
||||
GonkAutoMounter::~GonkAutoMounter()
|
||||
{
|
||||
bool result = RemountSystem(ReadOnly);
|
||||
free(mDevice);
|
||||
|
||||
if (!result) {
|
||||
// Don't take any chances when remounting as read-only fails, just reboot.
|
||||
Reboot();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GonkAutoMounter::Reboot()
|
||||
{
|
||||
// The android_reboot wrapper provides more safety, doing fancier read-only
|
||||
// remounting and attempting to sync() the filesystem first. If this fails
|
||||
// our only hope is to force a reboot directly without these protections.
|
||||
// For more, see system/core/libcutils/android_reboot.c
|
||||
LOGE("Could not remount %s as read-only, forcing a system reboot.",
|
||||
kGonkSystemPath);
|
||||
LogFlush();
|
||||
|
||||
if (android_reboot(ANDROID_RB_RESTART, 0, nullptr) != 0) {
|
||||
LOGE("Safe system reboot failed, attempting to force");
|
||||
LogFlush();
|
||||
|
||||
if (reboot(RB_AUTOBOOT) != 0) {
|
||||
LOGE("CRITICAL: Failed to force restart");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
MountAccessToString(MountAccess access)
|
||||
{
|
||||
switch (access) {
|
||||
case ReadOnly: return "read-only";
|
||||
case ReadWrite: return "read-write";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GonkAutoMounter::RemountSystem(MountAccess access)
|
||||
{
|
||||
if (!UpdateMountStatus()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mAccess == access) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long flags = MS_REMOUNT;
|
||||
if (access == ReadOnly) {
|
||||
flags |= MS_RDONLY;
|
||||
// Give the system a chance to flush file buffers
|
||||
sync();
|
||||
}
|
||||
|
||||
if (!MountSystem(flags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check status again to verify /system has been properly remounted
|
||||
if (!UpdateMountStatus()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mAccess != access) {
|
||||
LOGE("Updated mount status %s should be %s",
|
||||
MountAccessToString(mAccess),
|
||||
MountAccessToString(access));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GonkAutoMounter::UpdateMountStatus()
|
||||
{
|
||||
FILE *mountsFile = NS_tfopen(kGonkMountsPath, "r");
|
||||
|
||||
if (mountsFile == nullptr) {
|
||||
LOGE("Error opening %s: %s", kGonkMountsPath, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
// /proc/mounts returns a 0 size from fstat, so we use the same
|
||||
// pre-allocated buffer size that ADB does here
|
||||
const int mountsMaxSize = 4096;
|
||||
char mountData[mountsMaxSize];
|
||||
size_t read = fread(mountData, 1, mountsMaxSize - 1, mountsFile);
|
||||
mountData[read + 1] = '\0';
|
||||
|
||||
if (ferror(mountsFile)) {
|
||||
LOGE("Error reading %s, %s", kGonkMountsPath, strerror(errno));
|
||||
fclose(mountsFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
char *token, *tokenContext;
|
||||
bool foundSystem = false;
|
||||
|
||||
for (token = strtok_r(mountData, "\n", &tokenContext);
|
||||
token;
|
||||
token = strtok_r(nullptr, "\n", &tokenContext))
|
||||
{
|
||||
if (ProcessMount(token)) {
|
||||
foundSystem = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(mountsFile);
|
||||
|
||||
if (!foundSystem) {
|
||||
LOGE("Couldn't find %s mount in %s", kGonkSystemPath, kGonkMountsPath);
|
||||
}
|
||||
return foundSystem;
|
||||
}
|
||||
|
||||
bool
|
||||
GonkAutoMounter::ProcessMount(const char *mount)
|
||||
{
|
||||
const int strSize = 256;
|
||||
char mountDev[strSize];
|
||||
char mountDir[strSize];
|
||||
char mountAccess[strSize];
|
||||
|
||||
int rv = sscanf(mount, "%255s %255s %*s %255s %*d %*d\n",
|
||||
mountDev, mountDir, mountAccess);
|
||||
mountDev[strSize - 1] = '\0';
|
||||
mountDir[strSize - 1] = '\0';
|
||||
mountAccess[strSize - 1] = '\0';
|
||||
|
||||
if (rv != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(kGonkSystemPath, mountDir) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
free(mDevice);
|
||||
mDevice = strdup(mountDev);
|
||||
mAccess = Unknown;
|
||||
|
||||
char *option, *optionContext;
|
||||
for (option = strtok_r(mountAccess, ",", &optionContext);
|
||||
option;
|
||||
option = strtok_r(nullptr, ",", &optionContext))
|
||||
{
|
||||
if (strcmp("ro", option) == 0) {
|
||||
mAccess = ReadOnly;
|
||||
break;
|
||||
} else if (strcmp("rw", option) == 0) {
|
||||
mAccess = ReadWrite;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the given block device as read-write or read-only, using the BLKROSET
|
||||
* ioctl.
|
||||
*/
|
||||
static void SetBlockReadWriteStatus(const char *blockdev, bool setReadOnly) {
|
||||
int fd;
|
||||
int roMode = setReadOnly ? 1 : 0;
|
||||
|
||||
fd = open(blockdev, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKROSET, &roMode) == -1) {
|
||||
LOGE("Error setting read-only mode on %s to %s: %s", blockdev,
|
||||
setReadOnly ? "true": "false", strerror(errno));
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GonkAutoMounter::MountSystem(unsigned long flags)
|
||||
{
|
||||
if (!mDevice) {
|
||||
LOGE("No device was found for %s", kGonkSystemPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Without setting the block device ro mode to false, we get a permission
|
||||
// denied error while trying to remount it in read-write.
|
||||
SetBlockReadWriteStatus(mDevice, (flags & MS_RDONLY));
|
||||
|
||||
const char *readOnly = flags & MS_RDONLY ? "read-only" : "read-write";
|
||||
int result = mount(mDevice, kGonkSystemPath, "none", flags, nullptr);
|
||||
|
||||
if (result != 0) {
|
||||
LOGE("Error mounting %s as %s: %s", kGonkSystemPath, readOnly,
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGI("Mounted %s partition as %s", kGonkSystemPath, readOnly);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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 AUTOMOUNTER_GONK_H__
|
||||
#define AUTOMOUNTER_GONK_H__
|
||||
|
||||
typedef enum {
|
||||
ReadOnly,
|
||||
ReadWrite,
|
||||
Unknown
|
||||
} MountAccess;
|
||||
|
||||
/**
|
||||
* This class will remount the /system partition as read-write in Gonk to allow
|
||||
* the updater write access. Upon destruction, /system will be remounted back to
|
||||
* read-only. If something causes /system to remain read-write, this class will
|
||||
* reboot the device and allow the system to mount as read-only.
|
||||
*
|
||||
* Code inspired from AOSP system/core/adb/remount_service.c
|
||||
*/
|
||||
class GonkAutoMounter
|
||||
{
|
||||
public:
|
||||
GonkAutoMounter();
|
||||
~GonkAutoMounter();
|
||||
|
||||
MountAccess GetAccess() const
|
||||
{
|
||||
return mAccess;
|
||||
}
|
||||
|
||||
private:
|
||||
bool RemountSystem(MountAccess access);
|
||||
bool ForceRemountReadOnly();
|
||||
bool UpdateMountStatus();
|
||||
bool ProcessMount(const char *mount);
|
||||
bool MountSystem(unsigned long flags);
|
||||
void Reboot();
|
||||
|
||||
private:
|
||||
char *mDevice;
|
||||
MountAccess mAccess;
|
||||
};
|
||||
|
||||
#endif // AUTOMOUNTER_GONK_H__
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* 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 <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "android/log.h"
|
||||
|
||||
#include "progressui.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoUpdater" , ## args)
|
||||
|
||||
using namespace std;
|
||||
|
||||
int InitProgressUI(int *argc, char ***argv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ShowProgressUI()
|
||||
{
|
||||
LOG("Starting to apply update ...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QuitProgressUI()
|
||||
{
|
||||
LOG("Finished applying update\n");
|
||||
}
|
||||
|
||||
void UpdateProgressUI(float progress)
|
||||
{
|
||||
assert(0.0f <= progress && progress <= 100.0f);
|
||||
|
||||
static const size_t kProgressBarLength = 50;
|
||||
static size_t sLastNumBars;
|
||||
size_t numBars = size_t(float(kProgressBarLength) * progress / 100.0f);
|
||||
if (numBars == sLastNumBars) {
|
||||
return;
|
||||
}
|
||||
sLastNumBars = numBars;
|
||||
|
||||
size_t numSpaces = kProgressBarLength - numBars;
|
||||
string bars(numBars, '=');
|
||||
string spaces(numSpaces, ' ');
|
||||
LOG("Progress [ %s%s ]\n", bars.c_str(), spaces.c_str());
|
||||
}
|
||||
|
|
@ -90,17 +90,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
|||
LOCAL_INCLUDES += [
|
||||
'/toolkit/xre',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
have_progressui = 1
|
||||
srcs += [
|
||||
'automounter_gonk.cpp',
|
||||
'progressui_gonk.cpp',
|
||||
]
|
||||
DISABLE_STL_WRAPPING = True
|
||||
OS_LIBS += [
|
||||
'cutils',
|
||||
'sysutils',
|
||||
]
|
||||
|
||||
if have_progressui == 0:
|
||||
srcs += [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue