mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Fetch Android ID from Waydroid
This commit is contained in:
parent
868207c387
commit
a45e9cc56e
6 changed files with 134 additions and 0 deletions
|
|
@ -38,3 +38,10 @@ Description[x-test]=xxAllow initialization of Waydroidxx
|
||||||
Policy=yes
|
Policy=yes
|
||||||
PolicyInactive=yes
|
PolicyInactive=yes
|
||||||
Persistence=session
|
Persistence=session
|
||||||
|
|
||||||
|
[org.kde.plasma.mobileshell.waydroidhelper.getandroidid]
|
||||||
|
Name=Fetch Android ID for Google Services
|
||||||
|
Description=Allow get Android ID of Waydroid container to activate Google services
|
||||||
|
Policy=yes
|
||||||
|
PolicyInactive=yes
|
||||||
|
Persistence=session
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ class WaydroidHelper : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
KAuth::ActionReply initialize(const QVariantMap &args);
|
KAuth::ActionReply initialize(const QVariantMap &args);
|
||||||
|
KAuth::ActionReply getandroidid(const QVariantMap &args);
|
||||||
};
|
};
|
||||||
|
|
||||||
KAuth::ActionReply WaydroidHelper::initialize(const QVariantMap &args)
|
KAuth::ActionReply WaydroidHelper::initialize(const QVariantMap &args)
|
||||||
|
|
@ -56,6 +57,30 @@ KAuth::ActionReply WaydroidHelper::initialize(const QVariantMap &args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KAuth::ActionReply WaydroidHelper::getandroidid(const QVariantMap &args)
|
||||||
|
{
|
||||||
|
Q_UNUSED(args);
|
||||||
|
|
||||||
|
QStringList arguments = {u"shell"_s,
|
||||||
|
u"sqlite3"_s,
|
||||||
|
u"/data/data/com.google.android.gsf/databases/gservices.db"_s,
|
||||||
|
u"select value from main where name = \"android_id\""_s};
|
||||||
|
|
||||||
|
QProcess *process = new QProcess(this);
|
||||||
|
process->start(WAYDROID_COMMAND, arguments);
|
||||||
|
process->waitForFinished();
|
||||||
|
const QString androidId = process->readAllStandardOutput().trimmed();
|
||||||
|
|
||||||
|
if (process->exitCode() == 0) {
|
||||||
|
KAuth::ActionReply reply;
|
||||||
|
reply.addData("android_id"_L1, androidId);
|
||||||
|
return reply;
|
||||||
|
} else {
|
||||||
|
qCWarning(WAYDROIDHELPER) << "Failed to get Android ID: " << process->readAllStandardError();
|
||||||
|
return KAuth::ActionReply::HelperErrorReply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KAUTH_HELPER_MAIN("org.kde.plasma.mobileshell.waydroidhelper", WaydroidHelper)
|
KAUTH_HELPER_MAIN("org.kde.plasma.mobileshell.waydroidhelper", WaydroidHelper)
|
||||||
|
|
||||||
#include "waydroidhelper.moc"
|
#include "waydroidhelper.moc"
|
||||||
|
|
@ -89,6 +89,31 @@ void WaydroidState::refreshSessionInfo()
|
||||||
Q_EMIT ipAddressChanged();
|
Q_EMIT ipAddressChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WaydroidState::refreshAndroidId()
|
||||||
|
{
|
||||||
|
if (m_status != Initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KAuth::Action writeAction(u"org.kde.plasma.mobileshell.waydroidhelper.getandroidid"_s);
|
||||||
|
writeAction.setHelperId(u"org.kde.plasma.mobileshell.waydroidhelper"_s);
|
||||||
|
|
||||||
|
KAuth::ExecuteJob *job = writeAction.execute();
|
||||||
|
job->start();
|
||||||
|
|
||||||
|
connect(job, &KAuth::ExecuteJob::finished, this, [this](KJob *job, auto) {
|
||||||
|
KAuth::ExecuteJob *executeJob = dynamic_cast<KAuth::ExecuteJob *>(job);
|
||||||
|
if (executeJob->error() == 0) {
|
||||||
|
m_androidId = executeJob->data()["android_id"].toString();
|
||||||
|
} else {
|
||||||
|
m_androidId = "";
|
||||||
|
qCWarning(WAYDROIDINTEGRATIONPLUGIN) << "KAuth returned an error code:" << executeJob->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT androidIdChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void WaydroidState::refreshPropsInfo()
|
void WaydroidState::refreshPropsInfo()
|
||||||
{
|
{
|
||||||
if (m_sessionStatus != SessionRunning) {
|
if (m_sessionStatus != SessionRunning) {
|
||||||
|
|
@ -267,6 +292,11 @@ QString WaydroidState::errorMessage() const
|
||||||
return m_errorMessage;
|
return m_errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString WaydroidState::androidId() const
|
||||||
|
{
|
||||||
|
return m_androidId;
|
||||||
|
}
|
||||||
|
|
||||||
bool WaydroidState::multiWindows() const
|
bool WaydroidState::multiWindows() const
|
||||||
{
|
{
|
||||||
return m_multiWindows;
|
return m_multiWindows;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class WaydroidState : public QObject
|
||||||
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
|
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
|
||||||
Q_PROPERTY(SessionStatus sessionStatus READ sessionStatus NOTIFY sessionStatusChanged)
|
Q_PROPERTY(SessionStatus sessionStatus READ sessionStatus NOTIFY sessionStatusChanged)
|
||||||
Q_PROPERTY(QString ipAddress READ ipAddress NOTIFY ipAddressChanged)
|
Q_PROPERTY(QString ipAddress READ ipAddress NOTIFY ipAddressChanged)
|
||||||
|
Q_PROPERTY(QString androidId READ androidId NOTIFY androidIdChanged)
|
||||||
Q_PROPERTY(QString errorTitle READ errorTitle NOTIFY errorTitleChanged)
|
Q_PROPERTY(QString errorTitle READ errorTitle NOTIFY errorTitleChanged)
|
||||||
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
|
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
|
||||||
Q_PROPERTY(bool multiWindows READ multiWindows WRITE setMultiWindows NOTIFY multiWindowsChanged)
|
Q_PROPERTY(bool multiWindows READ multiWindows WRITE setMultiWindows NOTIFY multiWindowsChanged)
|
||||||
|
|
@ -83,6 +84,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void refreshSupportsInfo();
|
Q_INVOKABLE void refreshSupportsInfo();
|
||||||
Q_INVOKABLE void refreshSessionInfo();
|
Q_INVOKABLE void refreshSessionInfo();
|
||||||
|
Q_INVOKABLE void refreshAndroidId();
|
||||||
Q_INVOKABLE void refreshPropsInfo();
|
Q_INVOKABLE void refreshPropsInfo();
|
||||||
Q_INVOKABLE void resetError();
|
Q_INVOKABLE void resetError();
|
||||||
Q_INVOKABLE void initialize(const SystemType systemType, const RomType romType, const bool forced = false);
|
Q_INVOKABLE void initialize(const SystemType systemType, const RomType romType, const bool forced = false);
|
||||||
|
|
@ -93,6 +95,7 @@ public:
|
||||||
Status status() const;
|
Status status() const;
|
||||||
SessionStatus sessionStatus() const;
|
SessionStatus sessionStatus() const;
|
||||||
QString ipAddress() const;
|
QString ipAddress() const;
|
||||||
|
QString androidId() const;
|
||||||
QString errorTitle() const;
|
QString errorTitle() const;
|
||||||
QString errorMessage() const;
|
QString errorMessage() const;
|
||||||
bool multiWindows() const;
|
bool multiWindows() const;
|
||||||
|
|
@ -111,6 +114,7 @@ Q_SIGNALS:
|
||||||
void ueventChanged();
|
void ueventChanged();
|
||||||
void errorTitleChanged();
|
void errorTitleChanged();
|
||||||
void errorMessageChanged();
|
void errorMessageChanged();
|
||||||
|
void androidIdChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Status m_status{NotInitialized};
|
Status m_status{NotInitialized};
|
||||||
|
|
@ -118,6 +122,7 @@ private:
|
||||||
QString m_ipAddress{""};
|
QString m_ipAddress{""};
|
||||||
QString m_errorTitle{""};
|
QString m_errorTitle{""};
|
||||||
QString m_errorMessage{""};
|
QString m_errorMessage{""};
|
||||||
|
QString m_androidId{""};
|
||||||
|
|
||||||
// Waydroid props. See https://docs.waydro.id/usage/waydroid-prop-options
|
// Waydroid props. See https://docs.waydro.id/usage/waydroid-prop-options
|
||||||
bool m_multiWindows{false};
|
bool m_multiWindows{false};
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ ColumnLayout {
|
||||||
text: i18n("IP address")
|
text: i18n("IP address")
|
||||||
description: AIP.WaydroidState.ipAddress
|
description: AIP.WaydroidState.ipAddress
|
||||||
trailing: PC3.Button {
|
trailing: PC3.Button {
|
||||||
|
visible: AIP.WaydroidState.ipAddress !== ""
|
||||||
text: i18n('Copy')
|
text: i18n('Copy')
|
||||||
icon.name: 'edit-copy-symbolic'
|
icon.name: 'edit-copy-symbolic'
|
||||||
onClicked: AIP.WaydroidState.copyToClipboard(AIP.WaydroidState.ipAddress)
|
onClicked: AIP.WaydroidState.copyToClipboard(AIP.WaydroidState.ipAddress)
|
||||||
|
|
@ -39,6 +40,12 @@ ColumnLayout {
|
||||||
onClicked: AIP.WaydroidState.stopSession()
|
onClicked: AIP.WaydroidState.stopSession()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormCard.FormButtonDelegate {
|
||||||
|
id: quickSettingsButton
|
||||||
|
text: i18n("Certify my device for Google Play Protect")
|
||||||
|
onClicked: kcm.push("WaydroidGooglePlayProtectConfigurationPage.qml")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some informations as IP address can take time to be set by Waydroid
|
// Some informations as IP address can take time to be set by Waydroid
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Florian RICHER <florian.richer@protonmail.com>
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls as QQC2
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
import org.kde.kcmutils as KCM
|
||||||
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
|
import org.kde.plasma.private.mobileshell.waydroidintegrationplugin as AIP
|
||||||
|
|
||||||
|
KCM.SimpleKCM {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
|
||||||
|
title: i18n("Google Play Protect configuration")
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (AIP.WaydroidState.androidId === "") {
|
||||||
|
AIP.WaydroidState.refreshAndroidId()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WaydroidLoader {
|
||||||
|
visible: AIP.WaydroidState.androidId === ""
|
||||||
|
text: i18n("We fetching your Android ID.\nIt can take a few seconds.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
visible: AIP.WaydroidState.androidId !== ""
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent
|
||||||
|
anchors.leftMargin: Kirigami.Units.largeSpacing
|
||||||
|
anchors.right: parent
|
||||||
|
anchors.rightMargin: Kirigami.Units.largeSpacing
|
||||||
|
spacing: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
|
Kirigami.PlaceholderMessage {
|
||||||
|
explanation: i18n("When launching waydroid with GAPPS for the first time you will be notified that the device is not certified for Google Play Protect. To self certify your device, paste the Android ID on the field in the website. Then, give the Google services some minutes to reflect the change and restart waydroid.")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.Button {
|
||||||
|
text: i18nc("@action:button", "Copy Android ID and open the website")
|
||||||
|
icon.name: 'edit-copy-symbolic'
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
onClicked: {
|
||||||
|
AIP.WaydroidState.copyToClipboard(AIP.WaydroidState.androidId)
|
||||||
|
Qt.openUrlExternally("https://www.google.com/android/uncertified")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue