10 votos

Firefox Quantum para Android - ¿copia de seguridad del perfil sin Root?

En Firefox Quantum para Android (en un teléfono no rooteado), ¿cómo hago una copia de seguridad de mi perfil en otro lugar? Esto sería fácil si mi teléfono estuviera rooteado (sólo hay que acceder a la carpeta directamente y copiarla en otro lugar), pero no está rooteado.

He probado numerosas cosas diferentes, algunas de las cuales se han acercado de forma frustrante, pero nada ha funcionado:

  • Utilizar una aplicación como Helium Backup que utiliza adb para hacer una copia de seguridad de los datos de la aplicación. Esto funciona para algunas aplicaciones, pero para Firefox me da un cuadro de diálogo "Backup Disallowed" con el mensaje "Firefox has disallowed backup of application data. Por favor, deja un comentario al desarrollador de Firefox y pídele que permita la copia de seguridad de los datos de la aplicación".

  • Utilizar el navegador para navegar hasta el directorio del perfil e intentar descargar los elementos desde allí. Puedo ver claramente mi perfil yendo a file:///data/data/org.mozilla.firefox/files/mozilla/r3dact3d.default/, y teóricamente los archivos individuales podrían descargarse con el tiempo suficiente. Pero al intentar abrir cualquier cosa sólo se navega hacia ella. Esto "funciona" para los archivos de texto como el .ini, ya que puedo copiar y pegar manualmente su contenido, pero no para los archivos binarios (como el importantísimo browser.db), que siempre abre una página en blanco.

  • Haciendo lo anterior, pero utilizando la depuración USB y abriendo WebIDE en el Firefox de mi portátil para hurgar. Puedo ejecutar Javascript arbitrario en la página que me muestra el directorio de mi perfil, pero nada me permite descargar los archivos que me muestra. Lo más cerca que puedo llegar es si modifico las etiquetas de anclaje para añadir un atributo de descarga (para que se descarguen en lugar de navegar), pero entonces todos los enlaces muestran un mensaje de error "No se puede descargar el archivo" en el pie de página (en lugar de "Se ha iniciado la descarga...", que es lo que yo esperaría). No tengo ni idea de lo que significa este mensaje de error en particular, y buscar en Google no ayuda.

  • Haciendo lo anterior, pero manteniendo pulsado sobre cada enlace y eligiendo Abrir con una App (frente a Abrir enlace en nueva pestaña, etc.). Si consigo que aparezca una aplicación del explorador de archivos, siempre me da un mensaje de error similar "Este elemento no se puede guardar".

  • Intentando decirle a Firefox (a través de about:config, quizás) que guarde o mueva mi perfil a un lugar diferente que no requiera Root para acceder. Aparentemente Firefox no permite tal cosa.

  • Tratando de encontrar alguna función de Firefox Sync que respalde un perfil en el móvil. Esta función no parece existir.

  • Encontrar un complemento que copie el perfil en otro lugar. Antes de Firefox Quantum, había un complemento llamado Copy Profile que hacía exactamente esto. El complemento ya no es compatible con Firefox Quantum y no puedo encontrar ningún sustituto.

  • Usando adb para downgradear manualmente Firefox para que Copy Profile vuelva a funcionar. Al menos un usuario tiene ya intentó algo similar El resultado es que los datos de la aplicación entre Firefox Quantum y Firefox no Quantum están configurados de forma tan diferente que la aplicación recién degradada se bloquea inmediatamente al abrirla.

Me cuesta creer que una tarea tan importante y sencilla como hacer una copia de seguridad de mi perfil de Firefox sea imposible en Android no rooteado. ¿Alguien más se ha encontrado con este problema o alguno similar? ¿Alguna solución o sugerencia?

Gracias.

3voto

regulatethis Puntos 1138

Yo tenía el mismo problema y me inspiré en tu idea de utilizar WebIDE. Resulta que es posible acceder a los archivos de perfil a través de JavaScript, al menos en mi Firefox para Android versión 59.0.2, pero esto sólo ayuda parcialmente a respaldar todos los datos del perfil.

Principio

Se puede acceder al contenido del archivo mediante Ajax ( ver aquí ), también si son binarios ( referencia ). Sin embargo, parece que sólo se puede acceder a los archivos que están en el directorio actual o que están en un subdirectorio.

Por ejemplo, el contenido de browser.db se puede acceder navegando a file:///data/data/org.mozilla.firefox/files/mozilla/XXXXXXXX.default/ y luego ejecutar en la consola a través de WebIDE:

var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "browser.db");
xmlhttp.responseType = "arraybuffer";
xmlhttp.send();

El resultado se almacenará en xmlhttp.response como un arraybuffer. Si los datos no son binarios, "text" puede utilizarse en lugar de "arraybuffer" .

Para los archivos pequeños y no binarios puede bastar con copiarlos en el portapapeles con copy(xmlhttp.responseText) pero en el caso de los archivos de mayor tamaño puede producirse un error de falta de memoria.

La misma técnica puede utilizarse para obtener un listado de archivos y directorios. El problema es que esto (al menos para mí) sólo funcionaba para el directorio al que se navegaba, pero no para los subdirectorios. Los datos devueltos son una lista de archivos como texto plano:

300: file:///data/data/org.mozilla.firefox/files/mozilla/XXXXXXXX.default/
200: filename content-length last-modified file-type
201: AlternateServices.txt 0 Thu,%2010%20May%202018%2015:33:20%20GMT FILE 
201: OfflineCache 0 Thu,%2009%20Nov%202017%2018:28:54%20GMT DIRECTORY
...

Copia de seguridad

Para completar, aquí hay dos scripts que utilicé para respaldar los archivos. Ambos son sólo scripts rápidos y mínimos. Los datos se transfieren a un servidor Python que se ejecuta en el ordenador, que luego los almacena.

Es importante: Sólo hacen una copia de seguridad del archivos en el directorio actual, pero no en los directorios (véase la limitación anterior). Sin embargo, dado que la mayor parte del perfil está en el directorio root, esto podría ser suficiente. Si desea almacenar los archivos en los subdirectorios también necesita pegar y ejecutar el JavaScript de nuevo para cada directorio. Los directorios necesarios serán creados por el servidor.

Servidor Python (guardar esto como server.py y luego ejecutar, por ejemplo, con python3 server.py 2222 dependiendo del puerto que quiera utilizar)

import os
from http.server import BaseHTTPRequestHandler, HTTPServer

class FileReceiveHandler(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()

    def do_POST(self):
        content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
        post_data = self.rfile.read(content_length) # <--- Gets the data itself
        print(self.path)

        # Store file
        relative_file_path = os.path.join('received_files', self.path.lstrip('/'))
        directories = os.path.dirname(relative_file_path)
        os.makedirs(directories, exist_ok=True)
        with open(relative_file_path, 'wb') as f:
            f.write(post_data)

        self._set_headers()
        self.wfile.write(b'received')

if __name__ == '__main__':
    from sys import argv
    port = int(argv[1]) if len(argv) == 2 else 80
    server_address = ('', port)
    httpd = HTTPServer(server_address, FileReceiveHandler)
    print('Starting server')
    httpd.serve_forever()

Este es la fuente que he utilizado como referencia para el servidor.

Fuente de JavaScript para el navegador

Adapte las dos primeras líneas a la ruta de su propio perfil y a la dirección IP y puerto locales. A continuación, pegue este script directamente en la consola de WebIDE con el navegador navegado al directorio del perfil.

var profile_basepath = "file:///data/data/org.mozilla.firefox/files/mozilla/XXXXXXXX.default";
var server = "http://<your_local_ip>:2222";

function send() {
    var list_xmlhttp = new XMLHttpRequest();

    // Get files
    list_xmlhttp.onreadystatechange = function() {
        if(list_xmlhttp.status == 200 && list_xmlhttp.readyState == 4){
            itemslist = list_xmlhttp.response.split('\n');

            for (var i = 0; i < itemslist.length; i++) {
                if (itemslist[i].startsWith('201:')) {
                    parts = itemslist[i].split(' ');
                    if (parts[4] == 'FILE') {
                        handleFile(parts);
                    }
                }
            }
            console.log(itemslist);
        }
    };
    list_xmlhttp.open("GET", window.location.href, true);
    list_xmlhttp.responseType = "text";
    list_xmlhttp.send();
}

function handleFile(parts) {
    var filename = JSON.parse(JSON.stringify(parts[1]));

    // Get file content
    var file_xmlhttp = new XMLHttpRequest();
    file_xmlhttp.onreadystatechange = function() {
        if(file_xmlhttp.status == 200 && file_xmlhttp.readyState == 4){
            // Send file
            var filepath = window.location.href.substring(profile_basepath.length) + filename;
            var send_xmlhttp = new XMLHttpRequest();
            send_xmlhttp.open("POST", server + filepath, true);
            send_xmlhttp.send(file_xmlhttp.response);

            console.log(filepath + " sent");
        }
    }
    file_xmlhttp.open("GET", window.location.href + parts[1], true);
    file_xmlhttp.responseType = "arraybuffer";
    file_xmlhttp.send();
}

send();

Puede tardar un tiempo hasta que el script haya terminado.

0 votos

Estoy en el mismo barco que el OP. Lamentablemente este script ya no funciona porque las solicitudes de origen cruzado se bloquean con las versiones modernas de Firefox/Fennec: Solicitud de origen cruzado bloqueada: La política del mismo origen no permite leer el recurso remoto en file:///data/data/org.mozilla.fennec_fdroid/files/mozilla/w9ae812s.default/webappsstore.sqlite-wal. (Razón: petición CORS no http).

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X