Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package android-file-transfer-linux for
openSUSE:Factory checked in at 2025-10-14 18:08:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/android-file-transfer-linux (Old)
and /work/SRC/openSUSE:Factory/.android-file-transfer-linux.new.18484
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "android-file-transfer-linux"
Tue Oct 14 18:08:03 2025 rev:4 rq:1311166 version:4.5
Changes:
--------
---
/work/SRC/openSUSE:Factory/android-file-transfer-linux/android-file-transfer-linux.changes
2025-05-07 19:18:22.091963040 +0200
+++
/work/SRC/openSUSE:Factory/.android-file-transfer-linux.new.18484/android-file-transfer-linux.changes
2025-10-14 18:09:51.714705638 +0200
@@ -1,0 +2,24 @@
+Mon Oct 13 14:36:00 UTC 2025 - llyyr <[email protected]>
+
+- Update to version 4.5:
+ * fix invalid close session parameters (graceful shutdown - fixes switch
failure)
+ * fix qt5 compilation
+ * easier method to find zune codename
+ * support firmware upload/reboot device in UI
+ * add device property d235 - serial number (seems to match SN printed on
Zune's back)
+ * add Zune recovery instructions
+ * add flash cli command
+ * send object info in separate bulk packets
+ * add device-reboot cli command
+ * add firmware version to device properties
+ * undefined firmware (called in publicly available "Inside MTP Responder"
paper
+ * add EventCode enum values/ToString
+ * add mtp service extension codes
+ * send album cover in GUI
+ * use Supports(...) for attach cover context action
+ * add Library::AddCover, zune-import will upload cover automatically if
supported
+ * pass empty initialiser as empty bytearray while removing album cover
+ * add Supported() helper for ObjectPropertyCodes
+ * add MetadataPicture, fill it with decoded PICTURE props
+
+-------------------------------------------------------------------
Old:
----
android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1.tar.gz
New:
----
android-file-transfer-linux-4.5.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ android-file-transfer-linux.spec ++++++
--- /var/tmp/diff_new_pack.Zap1Ah/_old 2025-10-14 18:09:52.254728636 +0200
+++ /var/tmp/diff_new_pack.Zap1Ah/_new 2025-10-14 18:09:52.254728636 +0200
@@ -1,7 +1,7 @@
#
# spec file for package android-file-transfer-linux
#
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
Name: android-file-transfer-linux
Summary: Android file fransfer for Linux
-Version: 4.4.0~git.20250506T233238.058dbe1
+Version: 4.5
Release: 0
URL: https://github.com/whoozle/android-file-transfer-linux
Source0: %{name}-%{version}.tar.gz
++++++ _service ++++++
--- /var/tmp/diff_new_pack.Zap1Ah/_old 2025-10-14 18:09:52.286729999 +0200
+++ /var/tmp/diff_new_pack.Zap1Ah/_new 2025-10-14 18:09:52.290730169 +0200
@@ -3,16 +3,18 @@
<service name="obs_scm" mode="manual">
<param name="scm">git</param>
<param
name="url">https://github.com/whoozle/android-file-transfer-linux</param>
- <param name="revision">058dbe1b5405d8d46fdeec5573956762f0b9bded</param>
- <param name="versionprefix">4.4.0~git</param>
- <param name="versionformat">%ci.%h</param>
+ <param name="versionformat">@PARENT_TAG@</param>
+ <param name="versionrewrite-pattern">v(.*)</param>
+ <!-- <param name="revision">master</param> -->
+ <!-- <param name="versionprefix">4.5.0</param> -->
+ <!-- <param name="versionformat">%ci.%h</param> -->
<param name="changesgenerate">enable</param>
</service>
+ <service name="set_version" mode="manual"/>
<service name="tar" mode="manual"/>
<service name="recompress" mode="manual">
- <param name="file">*.tar</param>
<param name="compression">gz</param>
+ <param name="file">*.tar</param>
</service>
- <service name="set_version" mode="manual"/>
</services>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.Zap1Ah/_old 2025-10-14 18:09:52.310731022 +0200
+++ /var/tmp/diff_new_pack.Zap1Ah/_new 2025-10-14 18:09:52.318731362 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/whoozle/android-file-transfer-linux</param>
- <param
name="changesrevision">058dbe1b5405d8d46fdeec5573956762f0b9bded</param></service></servicedata>
+ <param
name="changesrevision">d5c18820c2bae0656043ca127f4b05b756ea1479</param></service></servicedata>
(No newline at EOF)
++++++ android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1.tar.gz ->
android-file-transfer-linux-4.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/.github/workflows/actions.yml
new/android-file-transfer-linux-4.5/.github/workflows/actions.yml
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/.github/workflows/actions.yml
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/.github/workflows/actions.yml
2025-05-15 00:28:05.000000000 +0200
@@ -4,7 +4,7 @@
jobs:
Linux:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
steps:
- name: Creating contiguous...
uses: ncipollo/release-action@v1
@@ -30,7 +30,7 @@
- name: Install Dependencies...
run: |
sudo apt-get update
- sudo apt-get -y install qt5-default qttools5-dev qttools5-dev-tools
libgtk2.0-dev libfuse-dev libmagic-dev libtag1-dev libssl-dev ninja-build cmake
+ sudo apt-get -y install qtbase5-dev qt5-qmake qttools5-dev
qttools5-dev-tools libgtk2.0-dev libfuse3-dev libfuse2 libmagic-dev libtag1-dev
libssl-dev ninja-build cmake
- name: Checking out sources...
uses: actions/checkout@v4
- name: Configuring...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/CMakeLists.txt
new/android-file-transfer-linux-4.5/CMakeLists.txt
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/CMakeLists.txt
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/CMakeLists.txt 2025-05-15
00:28:05.000000000 +0200
@@ -124,6 +124,7 @@
mtp/ptp/DataTypeCode.cpp
mtp/ptp/Device.cpp
mtp/ptp/DeviceProperty.cpp
+ mtp/ptp/EventCode.cpp
mtp/ptp/Messages.cpp
mtp/ptp/ObjectFormat.cpp
mtp/ptp/ObjectProperty.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/README.md
new/android-file-transfer-linux-4.5/README.md
--- old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/README.md
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/README.md 2025-05-15
00:28:05.000000000 +0200
@@ -1,7 +1,7 @@
# Android File Transfer For Linux (FreeBSD and macOS, too!)
[](https://github.com/whoozle/android-file-transfer-linux/blob/master/LICENSE)
-[](https://github.com/whoozle/android-file-transfer-linux)
+[](https://github.com/whoozle/android-file-transfer-linux)
[](https://github.com/whoozle/android-file-transfer-linux/actions/workflows/actions.yml)
Android File Transfer for Linux — a reliable
[MTP](https://en.wikipedia.org/wiki/Media_Transfer_Protocol) client with
minimalistic UI similar to [Android File
Transfer](https://www.android.com/intl/en_us/filetransfer/).
@@ -168,6 +168,56 @@
Remember, if you want album art to be displayed, it must be named
'albumart.xxx' and placed *first* in the destination folder. Then copy other
files.
Also, note that FUSE could be 7-8 times slower than UI/CLI file transfer.
+### ZUNE firmware flashing/recovery
+
+1. Find Zune-Firmware-x86.msi on the internet
+2. Unpack it `7z x Zune-Firmware-x86.msi` in some directory, you should get
the following files there:
+
+```
+DracoBaselineCab FirmwareUpdateXml KeelBaselineCab PavoBaselineCab
ScorpiusBaselineCab
+```
+3. Find the name of your update in FirmwareUpdateXml. If you're not sure, open
[Zune Specifications](https://en.wikipedia.org/wiki/Zune#Specifications)
wikipedia page, find your model in "Official Model Numbers" row, and match with
"Codename".
+For instance Zune 4 model 1124 has codename "Scorpius".
+4. Unpack update for your device into some folder using cabextract:
`cabextract XXXXBaselineCab`.
+
+Here's content of all cabs:
+```
+├── Draco
+│ ├── EBoot.bin
+│ ├── Games.cab
+│ ├── nk.bin
+│ └── recovery.bin
+├── Keel
+│ ├── EBoot.bin
+│ ├── Games.cab
+│ ├── nk.bin
+│ └── recovery.bin
+├── Pavo
+│ ├── EXT.bin
+│ ├── NK.bin
+│ ├── Recovery.bin
+│ └── ZBoot.bin
+└── Scorpius
+ ├── EBoot.bin
+ ├── Games.cab
+ ├── nk.bin
+ ├── recovery.bin
+ └── xldr.bin
+```
+
+5. Flash firmware files using cli tool. Generally you don't need to flash
anything called `*boot*` or `*recovery*`.
+Original software starts with nk.bin, then EXT or Games.
+Here's an example of how I flash model 1395:
+```
+aft-mtp-cli -v -d 045e:063e # finds Zune HD 16Gb (model 1395)
+
+flash zune/Pavo/NK.bin
+flash zune/Pavo/EXT.bin
+device-reboot
+```
+6. Wait until your Zune restarts, it can take a minute or two.
+7. Voila, you don't need to fiddle with Zune software on windows anymore.
+
### Qt user interface
1. Start application, choose destination folder and click any button on
toolbar.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/android-file-transfer-linux.json
new/android-file-transfer-linux-4.5/android-file-transfer-linux.json
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/android-file-transfer-linux.json
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/android-file-transfer-linux.json
2025-05-15 00:28:05.000000000 +0200
@@ -13,7 +13,7 @@
"config-opts": [ "-DCMAKE_BUILD_TYPE=Release" ],
"sources": [{
"type": "git",
- "tag": "v4.5",
+ "tag": "v4.6",
"url": "https://github.com/whoozle/android-file-transfer-linux.git"
}]
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/cli/Session.cpp
new/android-file-transfer-linux-4.5/cli/Session.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/cli/Session.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/cli/Session.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -125,6 +125,8 @@
make_function([this](const LocalPath &path, const Path
&dst) -> void { Put(path, dst); }));
AddCommand("put", "<file> uploads file",
make_function([this](const LocalPath &path) -> void {
Put(path); }));
+ AddCommand("flash", "<file> sends file but set file format to
UndefinedFirmware(0xb802).",
+ make_function([this](const LocalPath &path) -> void {
Flash(path); }));
AddCommand("get", "<file> downloads file",
make_function([this](const Path &path) -> void {
Get(path); }));
@@ -189,6 +191,10 @@
make_function([this](const LocalPath &path) ->
void { ZuneImport(path); }));
}
+ if
(_session->GetDeviceInfo().Supports(mtp::OperationCode::RebootDevice)) {
+ AddCommand("device-reboot", "reboots device (Microsoft
specific?)", make_function([this]() -> void { RebootDevice(); }));
+ }
+
AddCommand("test-property-list", "test GetObjectPropList on
given object",
make_function([this](const Path &path) -> void {
TestObjectPropertyList(path); }));
@@ -771,7 +777,7 @@
}
}
- void Session::Put(mtp::ObjectId parentId, const LocalPath &src, const
std::string &targetFilename)
+ void Session::Put(mtp::ObjectId parentId, const LocalPath &src, const
std::string &targetFilename, mtp::ObjectFormat format)
{
using namespace mtp;
struct stat st = Stat(src);
@@ -827,9 +833,12 @@
auto stream = std::make_shared<ObjectInputStream>(src);
stream->SetTotal(stream->GetSize());
+ if (format == mtp::ObjectFormat::Any)
+ format = ObjectFormatFromFilename(src);
+
msg::ObjectInfo oi;
oi.Filename = filename;
- oi.ObjectFormat = ObjectFormatFromFilename(src);
+ oi.ObjectFormat = format;
oi.ObjectCompressedSize = stream->GetSize();
if (_showEvents)
@@ -1103,6 +1112,9 @@
}
}
+ void Session::RebootDevice()
+ { _session->RebootDevice(); }
+
void Session::ZuneInit()
{
if (!_library)
@@ -1124,7 +1136,7 @@
if (!meta)
throw std::runtime_error("no metadata");
- print("metadata: ", meta->Artist, " / ", meta->Album, " (",
meta->Year, ") / ", meta->Title);
+ print("metadata: ", meta->Artist, " / ", meta->Album, " (",
meta->Year, ") / ", meta->Title, " picture description: ",
meta->Picture.Description);
auto artist = _library->GetArtist(meta->Artist);
if (!artist)
@@ -1148,6 +1160,9 @@
auto songId = _library->CreateTrack(artist, album, format,
meta->Title, meta->Genre, meta->Track, filename, stream->GetSize());
_session->SendObject(stream);
+ if (!meta->Picture.Data.empty())
+ _library->AddCover(album, meta->Picture.Data);
+
_library->AddTrack(album, songId);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/cli/Session.h
new/android-file-transfer-linux-4.5/cli/Session.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/cli/Session.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/cli/Session.h 2025-05-15
00:28:05.000000000 +0200
@@ -114,7 +114,7 @@
{ Get(dst, srcId, true); }
void Cat(const Path &path);
void Rename(const Path & path, const std::string & newName);
- void Put(mtp::ObjectId parentId, const LocalPath &src, const
std::string &targetFilename = std::string());
+ void Put(mtp::ObjectId parentId, const LocalPath &src, const
std::string &targetFilename = std::string(), mtp::ObjectFormat format =
mtp::ObjectFormat::Any);
void Put(const LocalPath &src, const Path &dst);
mtp::ObjectId MakeDirectory(mtp::ObjectId parentId, const
std::string & name);
void ListObjects(const std::string & format);
@@ -137,6 +137,9 @@
void Put(const LocalPath &src)
{ Put(_cd, src); }
+ void Flash(const LocalPath &src)
+ { Put(_cd, src, {}, mtp::ObjectFormat::UndefinedFirmware); }
+
void Get(const Path &src)
{ Get(Resolve(src)); }
@@ -174,6 +177,7 @@
void ZuneInit();
void ZuneImport(const LocalPath & path);
+ void RebootDevice();
template <typename ...Args>
void AddCommand(const std::string &name, const std::string
&help, std::function<void(Args...)> && callback)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/fuse/fuse.cpp
new/android-file-transfer-linux-4.5/fuse/fuse.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/fuse/fuse.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/fuse/fuse.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -823,14 +823,14 @@
void Init (void *userdata, struct fuse_conn_info *conn)
{
mtp::debug("Init: fuse proto version: ", conn->proto_major,
".", conn->proto_minor,
- ", capability: 0x", mtp::hex(conn->capable_ext, 8),
+ ", capability: 0x", mtp::hex(conn->capable, 8),
", max readahead: ", conn->max_readahead, ", max write:
", conn->max_write
);
//If synchronous reads are chosen, Fuse will wait for reads to
complete before issuing any other requests.
//mtp is completely synchronous. you cannot have two
transaction in parallel, so you have to wait any operation to finish before
starting another one
- fuse_unset_feature_flag(conn, FUSE_CAP_ASYNC_READ);
+ conn->want &= ~FUSE_CAP_ASYNC_READ;
try { g_wrapper->Init(userdata, conn); } catch (const
std::exception &ex) { mtp::error("init failed:", ex.what()); }
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Library.cpp
new/android-file-transfer-linux-4.5/mtp/metadata/Library.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Library.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/metadata/Library.cpp
2025-05-15 00:28:05.000000000 +0200
@@ -52,7 +52,9 @@
debug("device supports ObjectFormat::Artist: ",
_artistSupported? "yes": "no");
{
auto propsSupported =
_session->GetObjectPropertiesSupported(ObjectFormat::AbstractAudioAlbum);
- _albumDateAuthoredSupported =
std::find(propsSupported.ObjectPropertyCodes.begin(),
propsSupported.ObjectPropertyCodes.end(), ObjectProperty::DateAuthored) !=
propsSupported.ObjectPropertyCodes.end();
+ _albumDateAuthoredSupported =
propsSupported.Supports(ObjectProperty::DateAuthored);
+ _albumCoverSupported =
propsSupported.Supports(ObjectProperty::RepresentativeSampleData);
+ mtp::debug("abstract album supports date authored: ",
_albumDateAuthoredSupported, ", cover: ", _albumCoverSupported);
}
_storage = storages.StorageIDs[0]; //picking up first storage.
@@ -405,6 +407,14 @@
tracks.insert(std::make_pair(ti.Name, ti.Index));
}
+ void Library::AddCover(AlbumPtr album, const mtp::ByteArray &data)
+ {
+ if (!album || !_albumCoverSupported)
+ return;
+
+ mtp::debug("sending ", data.size(), " bytes of album cover...");
+ _session->SetObjectPropertyAsArray(album->Id,
mtp::ObjectProperty::RepresentativeSampleData, data);
+ }
bool Library::Supported(const mtp::SessionPtr & session)
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Library.h
new/android-file-transfer-linux-4.5/mtp/metadata/Library.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Library.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/metadata/Library.h 2025-05-15
00:28:05.000000000 +0200
@@ -3,6 +3,7 @@
#include <mtp/ptp/ObjectId.h>
#include <mtp/ptp/ObjectFormat.h>
+#include <mtp/ByteArray.h>
#include <mtp/types.h>
#include <functional>
#include <memory>
@@ -68,6 +69,7 @@
ObjectId _musicFolder;
bool _artistSupported;
bool _albumDateAuthoredSupported;
+ bool _albumCoverSupported;
using ArtistMap = std::unordered_map<std::string, ArtistPtr>;
ArtistMap _artists;
@@ -102,6 +104,7 @@
bool HasTrack(const AlbumPtr & album, const std::string &name,
int trackIndex);
NewTrackInfo CreateTrack(const ArtistPtr & artist, const
AlbumPtr & album, ObjectFormat type, std::string name, const std::string &
genre, int trackIndex, const std::string &filename, size_t size);
void AddTrack(AlbumPtr album, const NewTrackInfo &ti);
+ void AddCover(AlbumPtr album, const mtp::ByteArray &data);
};
DECLARE_PTR(Library);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Metadata.cpp
new/android-file-transfer-linux-4.5/mtp/metadata/Metadata.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Metadata.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/metadata/Metadata.cpp
2025-05-15 00:28:05.000000000 +0200
@@ -1,4 +1,5 @@
#include <mtp/metadata/Metadata.h>
+#include <mtp/log.h>
#ifdef HAVE_TAGLIB
# include <fileref.h>
@@ -34,6 +35,30 @@
meta->Genre = tag->genre().to8Bit(true);
meta->Year = tag->year();
meta->Track = tag->track();
+
+#if TAGLIB_MAJOR_VERSION >= 2
+ for(auto & props : tag->complexProperties("PICTURE"))
+ {
+ auto &picture = meta->Picture;
+ for(auto &kv : props)
+ {
+ auto &name = kv.first;
+ auto &value = kv.second;
+ if (name == "data") {
+ auto data = value.toByteVector();
+ picture.Data.assign(data.begin(),
data.end());
+ } else if (name == "pictureType") {
+ picture.Type =
value.toString().to8Bit(true);
+ } else if (name == "mimeType") {
+ picture.MimeType =
value.toString().to8Bit(true);
+ } else if (name == "description") {
+ picture.Description =
value.toString().to8Bit(true);
+ } else {
+ mtp::debug("unhandled PICTURE property
", name.toCString(true));
+ }
+ }
+ }
+#endif
return meta;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Metadata.h
new/android-file-transfer-linux-4.5/mtp/metadata/Metadata.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/metadata/Metadata.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/metadata/Metadata.h 2025-05-15
00:28:05.000000000 +0200
@@ -2,6 +2,7 @@
#define AFTL_MTP_METADATA_METADATA_H
#include <mtp/types.h>
+#include <mtp/ByteArray.h>
#include <memory>
#include <string>
@@ -10,6 +11,14 @@
struct Metadata;
DECLARE_PTR(Metadata);
+ struct MetadataPicture
+ {
+ std::string Type;
+ std::string MimeType;
+ std::string Description;
+ mtp::ByteArray Data;
+ };
+
struct Metadata
{
std::string Title;
@@ -18,6 +27,7 @@
std::string Genre;
unsigned Year;
unsigned Track;
+ MetadataPicture Picture;
static MetadataPtr Read(const std::string & path);
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/DeviceProperty.values.h
new/android-file-transfer-linux-4.5/mtp/ptp/DeviceProperty.values.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/DeviceProperty.values.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/DeviceProperty.values.h
2025-05-15 00:28:05.000000000 +0200
@@ -31,17 +31,27 @@
ENUM_VALUE(Artist, 0x501e)
ENUM_VALUE(CopyrightInfo, 0x501f)
+ENUM_VALUE(SecureTime, 0xd101)
+ENUM_VALUE(DeviceCertificate, 0xd102)
+ENUM_VALUE(RevocationInfo, 0xd103)
+ENUM_VALUE(PlaysForSureID, 0xd131)
+
ENUM_VALUE(DeviceEUI64, 0xd210)
+ENUM_VALUE(FirmwareVersion, 0xd233)
+ENUM_VALUE(SerialNumber, 0xd235)
+
+ENUM_VALUE(FunctionalID, 0xd301)
+ENUM_VALUE(ModelID, 0xd302)
+ENUM_VALUE(UseDeviceStage, 0xd303)
ENUM_VALUE(SynchronizationPartner, 0xd401)
ENUM_VALUE(DeviceFriendlyName, 0xd402)
ENUM_VALUE(Volume, 0xd403)
ENUM_VALUE(SupportedFormatsOrdered, 0xd404)
ENUM_VALUE(DeviceIcon, 0xd405)
+ENUM_VALUE(SessionInitiatorVersionInfo, 0xd406)
+ENUM_VALUE(PerceivedDeviceType, 0xd407)
ENUM_VALUE(PlaybackRate, 0xd410)
ENUM_VALUE(PlaybackObject, 0xd411)
ENUM_VALUE(PlaybackContainerIndex, 0xd412)
ENUM_VALUE(PlaybackPosition, 0xd413)
-
-ENUM_VALUE(SessionInitiatorVersionInfo, 0xd406)
-ENUM_VALUE(PerceivedDeviceType, 0xd407)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/EventCode.cpp
new/android-file-transfer-linux-4.5/mtp/ptp/EventCode.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/EventCode.cpp
1970-01-01 01:00:00.000000000 +0100
+++ new/android-file-transfer-linux-4.5/mtp/ptp/EventCode.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -0,0 +1,15 @@
+#include <mtp/ptp/EventCode.h>
+#include <mtp/log.h>
+
+namespace mtp
+{
+ std::string ToString(EventCode code)
+ {
+ switch(code)
+ {
+# define ENUM_VALUE(NAME, VALUE)
ENUM_VALUE_TO_STRING(EventCode, NAME, VALUE)
+# include <mtp/ptp/EventCode.values.h>
+ ENUM_VALUE_TO_STRING_DEFAULT(OperationCode, code, 4);
+ }
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/EventCode.h
new/android-file-transfer-linux-4.5/mtp/ptp/EventCode.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/EventCode.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/EventCode.h 2025-05-15
00:28:05.000000000 +0200
@@ -1,3 +1,22 @@
+/*
+ This file is part of Android File Transfer For Linux.
+ Copyright (C) 2015-2025 Vladimir Menshakov
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
#ifndef AFTL_MTP_PTP_EVENTCODE_H
#define AFTL_MTP_PTP_EVENTCODE_H
@@ -7,26 +26,13 @@
{
enum struct EventCode : u16
{
- TransactionCancelled = 0x4001,
- ObjectAdded = 0x4002,
- ObjectRemoved = 0x4003,
- StoreAdded = 0x4004,
- StoreRemoved = 0x4005,
- DevicePropChanged = 0x4006,
- ObjectInfoChanged = 0x4007,
- DeviceInfoChanged = 0x4008,
- RequestObjectTransfer = 0x4009,
- StoreFull = 0x400a,
- DeviceReset = 0x400b,
- StorageInfoChanged = 0x400c,
- CaptureComplete = 0x400d,
- UnreportedStatus = 0x400e,
-
- ObjectPropChanged = 0xc801,
- ObjectPropDescChanged = 0xc802,
- ObjectReferenceChanged = 0xc803
+#define ENUM_VALUE(NAME, VALUE) ENUM_VALUE_DECL(NAME, VALUE)
+# include <mtp/ptp/EventCode.values.h>
+#undef ENUM_VALUE
};
DECLARE_ENUM(EventCode, u16);
+
+ std::string ToString(EventCode code);
}
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/EventCode.values.h
new/android-file-transfer-linux-4.5/mtp/ptp/EventCode.values.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/EventCode.values.h
1970-01-01 01:00:00.000000000 +0100
+++ new/android-file-transfer-linux-4.5/mtp/ptp/EventCode.values.h
2025-05-15 00:28:05.000000000 +0200
@@ -0,0 +1,17 @@
+ENUM_VALUE(TransactionCancelled, 0x4001)
+ENUM_VALUE(ObjectAdded, 0x4002)
+ENUM_VALUE(ObjectRemoved, 0x4003)
+ENUM_VALUE(StoreAdded, 0x4004)
+ENUM_VALUE(StoreRemoved, 0x4005)
+ENUM_VALUE(DevicePropChanged, 0x4006)
+ENUM_VALUE(ObjectInfoChanged, 0x4007)
+ENUM_VALUE(DeviceInfoChanged, 0x4008)
+ENUM_VALUE(RequestObjectTransfer, 0x4009)
+ENUM_VALUE(StoreFull, 0x400a)
+ENUM_VALUE(DeviceReset, 0x400b)
+ENUM_VALUE(StorageInfoChanged, 0x400c)
+ENUM_VALUE(CaptureComplete, 0x400d)
+ENUM_VALUE(UnreportedStatus, 0x400e)
+ENUM_VALUE(ObjectPropChanged, 0xc801)
+ENUM_VALUE(ObjectPropDescChanged, 0xc802)
+ENUM_VALUE(ObjectReferenceChanged, 0xc803)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Messages.cpp
new/android-file-transfer-linux-4.5/mtp/ptp/Messages.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Messages.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/Messages.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -61,4 +61,8 @@
return ss.str();
}
+ bool ObjectPropertiesSupported::Supports(ObjectProperty prop) const
+ { return std::find(ObjectPropertyCodes.begin(),
ObjectPropertyCodes.end(), prop) != ObjectPropertyCodes.end(); }
+
+
}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Messages.h
new/android-file-transfer-linux-4.5/mtp/ptp/Messages.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Messages.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/Messages.h 2025-05-15
00:28:05.000000000 +0200
@@ -219,6 +219,8 @@
{
std::vector<ObjectProperty> ObjectPropertyCodes;
+ bool Supports(ObjectProperty prop) const;
+
void Read(InputStream &stream)
{
stream >> ObjectPropertyCodes;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/ObjectFormat.values.h
new/android-file-transfer-linux-4.5/mtp/ptp/ObjectFormat.values.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/ObjectFormat.values.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/ObjectFormat.values.h
2025-05-15 00:28:05.000000000 +0200
@@ -36,8 +36,7 @@
ENUM_VALUE(M4a, 0xb215)
ENUM_VALUE(Artist, 0xb218)
-ENUM_VALUE(UndefinedFirmware, 0xb800)
-ENUM_VALUE(UndefinedFirmwareAndroid, 0xb802)
+ENUM_VALUE(UndefinedFirmware, 0xb802)
ENUM_VALUE(WindowsImageFormat, 0xb881)
ENUM_VALUE(UndefinedAudio, 0xb900)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/OperationCode.values.h
new/android-file-transfer-linux-4.5/mtp/ptp/OperationCode.values.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/OperationCode.values.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/OperationCode.values.h
2025-05-15 00:28:05.000000000 +0200
@@ -49,6 +49,7 @@
ENUM_VALUE(WMPMetadataRoundTrip, 0x9201)
ENUM_VALUE(WmpGetAcquiredContent, 0x9202)
+ENUM_VALUE(RebootDevice, 0x9204)
ENUM_VALUE(SendWMDRMPDAppRequest, 0x9212)
ENUM_VALUE(GetWMDRMPDAppResponse, 0x9213)
@@ -56,6 +57,17 @@
ENUM_VALUE(DisableTrustedFilesOperations, 0x9215)
ENUM_VALUE(EndTrustedAppSession, 0x9216)
+ENUM_VALUE(GetServiceIDs, 0x9301)
+ENUM_VALUE(GetServiceInfo, 0x9302)
+ENUM_VALUE(GetServiceCapabilities, 0x9303)
+ENUM_VALUE(GetServicePropDesc, 0x9304)
+ENUM_VALUE(GetServicePropList, 0x9305)
+ENUM_VALUE(SetServicePropList, 0x9306)
+ENUM_VALUE(UpdateObjectPropList, 0x9307)
+ENUM_VALUE(DeleteObjectPropList, 0x9308)
+ENUM_VALUE(DeleteServicePropList, 0x9309)
+ENUM_VALUE(GetFormatCapabilities, 0x930a)
+
ENUM_VALUE(SendTinyCLRData, 0x9401)
ENUM_VALUE(GetTinyCLRData, 0x9402)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/ResponseType.values.h
new/android-file-transfer-linux-4.5/mtp/ptp/ResponseType.values.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/ResponseType.values.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/ResponseType.values.h
2025-05-15 00:28:05.000000000 +0200
@@ -30,6 +30,8 @@
ENUM_VALUE(SessionAlreadyOpen, 0x201e)
ENUM_VALUE(TransactionCancelled, 0x201f)
ENUM_VALUE(SpecificationOfDestinationUnsupported, 0x2020)
+ENUM_VALUE(InvalidServiceID, 0xa301)
+ENUM_VALUE(InvalidServicePropCode, 0xa302)
ENUM_VALUE(TinyCLRNotResponding, 0xa401)
ENUM_VALUE(NoDataWaiting, 0xa402)
ENUM_VALUE(InvalidObjectPropCode, 0xa801)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Session.cpp
new/android-file-transfer-linux-4.5/mtp/ptp/Session.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Session.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/Session.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -105,7 +105,8 @@
void Session::Close()
{
scoped_mutex_lock l(_mutex);
- Send(OperationRequest(OperationCode::CloseSession, 0,
_sessionId));
+ Transaction transaction(this);
+ Send(OperationRequest(OperationCode::CloseSession,
transaction.Id));
ByteArray data, response;
ResponseType responseCode;
_packeter.Read(0, data, responseCode, response,
_defaultTimeout);
@@ -296,10 +297,25 @@
Send(OperationRequest(OperationCode::SendObjectInfo,
transaction.Id, storageId.Id, parentObject.Id));
{
DataRequest req(OperationCode::SendObjectInfo,
transaction.Id);
- OutputStream stream(req.Data);
- objectInfo.Write(stream);
- Container container(req);
- _packeter.Write(container.Data, _defaultTimeout);
+ if (_separateBulkWrites)
+ {
+ ByteArray data;
+ OutputStream os(data);
+ objectInfo.Write(os);
+ auto is =
std::make_shared<ByteArrayObjectInputStream>(data);
+
+ Container container(req, is);
+ _packeter.Write(container.Data,
_defaultTimeout);
+
+ _packeter.Write(is, _defaultTimeout);
+ }
+ else
+ {
+ OutputStream stream(req.Data);
+ objectInfo.Write(stream);
+ Container container(req);
+ _packeter.Write(container.Data,
_defaultTimeout);
+ }
}
ByteArray data, response;
ResponseType responseCode;
@@ -319,7 +335,7 @@
Container container(req, inputStream);
if (_separateBulkWrites)
{
-
_packeter.Write(std::make_shared<ByteArrayObjectInputStream>(container.Data),
timeout);
+ _packeter.Write(container.Data, timeout);
_packeter.Write(inputStream, timeout);
} else
_packeter.Write(std::make_shared<JoinedObjectInputStream>(std::make_shared<ByteArrayObjectInputStream>(container.Data),
inputStream), timeout);
@@ -534,6 +550,9 @@
void Session::EnableSecureFileOperations(u32 cmac[4])
{ RunTransaction(_defaultTimeout,
OperationCode::EnableTrustedFilesOperations, cmac[0], cmac[1], cmac[2],
cmac[3]); }
+ void Session::RebootDevice()
+ { RunTransaction(_defaultTimeout, OperationCode::RebootDevice); }
+
Session::ObjectEditSession::ObjectEditSession(const SessionPtr &
session, ObjectId objectId): _session(session), _objectId(objectId)
{ session->BeginEditObject(objectId); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Session.h
new/android-file-transfer-linux-4.5/mtp/ptp/Session.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/mtp/ptp/Session.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/mtp/ptp/Session.h 2025-05-15
00:28:05.000000000 +0200
@@ -143,6 +143,7 @@
//windows specific
void EnableSecureFileOperations(u32 cmac1[4]);
+ void RebootDevice();
static msg::DeviceInfo GetDeviceInfo(PipePacketer& packeter,
u32 transactionId, int timeout = 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/commandqueue.cpp
new/android-file-transfer-linux-4.5/qt/commandqueue.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/commandqueue.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/commandqueue.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -35,7 +35,7 @@
{ queue.finish(DirectoryId); }
void UploadFile::execute(CommandQueue &queue)
-{ queue.uploadFile(Filename); }
+{ queue.uploadFile(Filename, Format); }
void MakeDirectory::execute(CommandQueue &queue)
{ queue.createDirectory(Filename); }
@@ -99,7 +99,7 @@
addProgress(fi.size());
}
-void CommandQueue::uploadFile(const QString &filename)
+void CommandQueue::uploadFile(const QString &filename, mtp::ObjectFormat
format)
{
if (_aborted)
return;
@@ -107,7 +107,7 @@
QFileInfo fi(filename);
QString parentPath = fi.dir().path();
- qDebug() << "uploading file " << filename << ", parent: " << parentPath;
+ qDebug() << "uploading file " << filename << ", parent: " << parentPath
<< ", format: " << fromUtf8(mtp::ToString(format));
if (_directories.empty())
{
@@ -127,7 +127,7 @@
if (_model->parentObjectId() != parent.value()) //needed for
overwrite protection
_model->setParent(parent.value());
- _model->uploadFile(parent.value(), filename);
+ _model->uploadFile(parent.value(), filename, {}, format);
} catch(const std::exception &ex)
{ qDebug() << "uploading file " << filename << " failed: " <<
fromUtf8(ex.what()); }
@@ -208,6 +208,9 @@
_albums.insert(std::make_pair(dir, album));
}
+ if (!metadata->Picture.Data.empty())
+ _library->AddCover(album, metadata->Picture.Data);
+
if (_library->HasTrack(album, metadata->Title, metadata->Track)) {
qDebug() << "skipping" << filename << ", already uploaded";
return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/commandqueue.h
new/android-file-transfer-linux-4.5/qt/commandqueue.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/commandqueue.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/commandqueue.h 2025-05-15
00:28:05.000000000 +0200
@@ -66,7 +66,8 @@
struct UploadFile : public FileCommand
{
- UploadFile(const QString &filename) : FileCommand(filename) { }
+ mtp::ObjectFormat Format;
+ UploadFile(const QString &filename, mtp::ObjectFormat format) :
FileCommand(filename), Format(format) { }
void execute(CommandQueue &queue);
};
@@ -120,7 +121,7 @@
void loadLibrary();
void createDirectory(const QString &path);
- void uploadFile(const QString &file);
+ void uploadFile(const QString &file, mtp::ObjectFormat format);
void downloadFile(const QString &filename, mtp::ObjectId objectId);
void importFile(const QString &file);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/fileuploader.cpp
new/android-file-transfer-linux-4.5/qt/fileuploader.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/fileuploader.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/fileuploader.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -86,7 +86,7 @@
emit finished();
}
-void FileUploader::upload(QStringList files)
+void FileUploader::upload(QStringList files, mtp::ObjectFormat format)
{
_model->moveToThread(&_workerThread);
_total = 0;
@@ -113,7 +113,7 @@
if (fi.isFile())
{
- commands.push_back(new
UploadFile(next));
+ commands.push_back(new UploadFile(next,
format));
_total += fi.size();
}
else if (fi.isDir())
@@ -125,7 +125,7 @@
}
else if (currentFileInfo.isFile())
{
- commands.push_back(new UploadFile(currentFile));
+ commands.push_back(new UploadFile(currentFile, format));
_total += currentFileInfo.size();
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/fileuploader.h
new/android-file-transfer-linux-4.5/qt/fileuploader.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/fileuploader.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/fileuploader.h 2025-05-15
00:28:05.000000000 +0200
@@ -24,6 +24,7 @@
#include <QThread>
#include <QDateTime>
#include <mtp/types.h>
+#include <mtp/ptp/ObjectFormat.h>
#include <memory>
class MtpObjectsModel;
@@ -62,7 +63,7 @@
void tryCreateLibrary();
mtp::LibraryPtr library() const;
- void upload(QStringList files);
+ void upload(QStringList files, mtp::ObjectFormat format);
void importMusic(const QString & path);
void download(const QString &path, const QVector<mtp::ObjectId> &
objectIds);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mainwindow.cpp
new/android-file-transfer-linux-4.5/qt/mainwindow.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mainwindow.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/mainwindow.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -107,6 +107,8 @@
connect(_ui->actionShowThumbnails, SIGNAL(triggered(bool)),
SLOT(showThumbnails(bool)));
connect(_ui->actionRemoveCover, SIGNAL(triggered(bool)),
SLOT(removeCover()));
connect(_ui->actionAttachCover, SIGNAL(triggered(bool)),
SLOT(attachCover()));
+ connect(_ui->actionUploadFirmware, SIGNAL(triggered()),
SLOT(uploadFirmware()));
+ connect(_ui->actionRebootDevice, SIGNAL(triggered()),
SLOT(rebootDevice()));
connect(_objectModel, SIGNAL(onFilesDropped(QStringList)),
SLOT(onFilesDropped(QStringList)));
connect(_objectModel, SIGNAL(existingFileOverwrite(QString)),
SLOT(confirmOverwrite(QString)), Qt::BlockingQueuedConnection);
@@ -469,6 +471,9 @@
_ui->actionGoDown->setEnabled(rows.size() == 1);
_ui->actionBack->setEnabled(!_history.empty());
+ _ui->actionUploadFirmware->setEnabled(_session?
_session->GetDeviceInfo().Supports(mtp::ObjectFormat::UndefinedFirmware):
false);
+ _ui->actionRebootDevice->setEnabled(_session?
_session->GetDeviceInfo().Supports(mtp::OperationCode::RebootDevice): false);
+
QStringList statusList;
for(const auto & h : _history)
statusList.push_back(h.first);
@@ -558,12 +563,7 @@
visited.insert(format);
auto supportedProperties =
_session->GetObjectPropertiesSupported(format);
- auto & properties =
supportedProperties.ObjectPropertyCodes;
- auto it = std::find(properties.begin(),
properties.end(), mtp::ObjectProperty::RepresentativeSampleData);
- if (it != properties.end()) {
- showRSMenu = true;
- break;
- }
+ showRSMenu =
supportedProperties.Supports(mtp::ObjectProperty::RepresentativeSampleData);
} catch (const std::exception & ex) {
qWarning() << "checking representative sample failed";
}
@@ -611,12 +611,12 @@
saveGeometry("create-directory-dialog", d);
}
-void MainWindow::uploadFiles(const QStringList &files)
+void MainWindow::uploadFiles(const QStringList &files, mtp::ObjectFormat
format)
{
if (files.isEmpty())
return;
- qDebug() << "uploadFiles " << files;
+ qDebug() << "uploadFiles " << files << ", format: " <<
fromUtf8(mtp::ToString(format));
_uploadAnswer = 0;
_proxyModel->setSourceModel(NULL);
ProgressDialog progressDialog(this);
@@ -628,7 +628,7 @@
connect(_uploader, SIGNAL(uploadStarted(QString)), &progressDialog,
SLOT(setFilename(QString)));
connect(_uploader, SIGNAL(finished()), &progressDialog, SLOT(accept()));
connect(&progressDialog, SIGNAL(abort()), _uploader, SLOT(abort()));
- _uploader->upload(files);
+ _uploader->upload(files, format);
progressDialog.exec();
@@ -987,15 +987,40 @@
QItemSelectionModel *selection =_ui->listView->selectionModel();
QModelIndexList rows = selection->selectedRows();
- mtp::ByteArray value;
-
for(QModelIndex row : rows)
{
row = mapIndex(row);
auto id = _objectModel->objectIdAt(row.row());
try
- { _session->SetObjectPropertyAsArray(id,
mtp::ObjectProperty::RepresentativeSampleData, value); }
+ { _session->SetObjectPropertyAsArray(id,
mtp::ObjectProperty::RepresentativeSampleData, {}); }
catch(const std::exception & ex)
{ qWarning() << "failed to remove cover:" << ex.what(); }
}
}
+
+void MainWindow::uploadFirmware()
+{
+ QFileDialog d(this);
+
+ QSettings settings;
+ {
+ QVariant ld = settings.value("the-latest-firmware-directory");
+ if (ld.isValid())
+ d.setDirectory(ld.toString());
+ }
+
+ d.setAcceptMode(QFileDialog::AcceptOpen);
+ d.setFileMode(QFileDialog::ExistingFiles);
+ d.setOption(QFileDialog::ShowDirsOnly, false);
+ d.setOption(QFileDialog::ReadOnly, true);
+ restoreGeometry("upload-firmware", d);
+ if (!d.exec())
+ return;
+
+ saveGeometry("upload-firmware", d);
+ settings.setValue("the-latest-firmware-directory",
d.directory().absolutePath());
+ uploadFiles(d.selectedFiles(), mtp::ObjectFormat::UndefinedFirmware);
+}
+
+void MainWindow::rebootDevice()
+{ _session->RebootDevice(); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mainwindow.h
new/android-file-transfer-linux-4.5/qt/mainwindow.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mainwindow.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/mainwindow.h 2025-05-15
00:28:05.000000000 +0200
@@ -25,6 +25,7 @@
#include <QVector>
#include <QByteArray>
#include <mtp/ptp/ObjectId.h>
+#include <mtp/ptp/ObjectFormat.h>
#include <mtp/types.h>
namespace Ui {
@@ -95,7 +96,7 @@
void renameFile();
void deleteFiles();
void downloadFiles(const QVector<mtp::ObjectId> &objects);
- void uploadFiles(const QStringList &files);
+ void uploadFiles(const QStringList &files, mtp::ObjectFormat format =
mtp::ObjectFormat::Any);
void onFilesDropped(const QStringList &files);
void onStorageChanged(int idx);
void validateClipboard();
@@ -104,6 +105,8 @@
void showThumbnails(bool enable);
void attachCover();
void removeCover();
+ void uploadFirmware();
+ void rebootDevice();
public slots:
void downloadFiles(const QString & path, const QVector<mtp::ObjectId>
&objects);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mainwindow.ui
new/android-file-transfer-linux-4.5/qt/mainwindow.ui
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mainwindow.ui
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/mainwindow.ui 2025-05-15
00:28:05.000000000 +0200
@@ -71,6 +71,9 @@
<addaction name="separator"/>
<addaction name="actionCreateDirectory"/>
<addaction name="separator"/>
+ <addaction name="actionUploadFirmware"/>
+ <addaction name="actionRebootDevice"/>
+ <addaction name="separator"/>
<addaction name="actionPaste"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
@@ -119,7 +122,7 @@
</action>
<action name="actionCreateDirectory">
<property name="text">
- <string>&CreateDirectory</string>
+ <string>&CreateDirectory...</string>
</property>
<property name="shortcut">
<string>Ctrl+N</string>
@@ -233,6 +236,16 @@
<string>Import individual music files</string>
</property>
</action>
+ <action name="actionUploadFirmware">
+ <property name="text">
+ <string>Upload Firmware...</string>
+ </property>
+ </action>
+ <action name="actionRebootDevice">
+ <property name="text">
+ <string>Reboot Device</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mtpobjectsmodel.cpp
new/android-file-transfer-linux-4.5/qt/mtpobjectsmodel.cpp
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mtpobjectsmodel.cpp
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/mtpobjectsmodel.cpp 2025-05-15
00:28:05.000000000 +0200
@@ -256,10 +256,12 @@
return noi.ObjectId;
}
-bool MtpObjectsModel::uploadFile(mtp::ObjectId parentObjectId, const QString
&filePath, QString filename)
+bool MtpObjectsModel::uploadFile(mtp::ObjectId parentObjectId, const QString
&filePath, QString filename, mtp::ObjectFormat format)
{
QFileInfo fileInfo(filePath);
- mtp::ObjectFormat objectFormat =
mtp::ObjectFormatFromFilename(toUtf8(filePath));
+ mtp::ObjectFormat objectFormat = format == mtp::ObjectFormat::Any?
+ mtp::ObjectFormatFromFilename(toUtf8(filePath)):
+ format;
if (filename.isEmpty())
filename = fileInfo.fileName();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mtpobjectsmodel.h
new/android-file-transfer-linux-4.5/qt/mtpobjectsmodel.h
---
old/android-file-transfer-linux-4.4.0~git.20250506T233238.058dbe1/qt/mtpobjectsmodel.h
2025-05-07 00:32:38.000000000 +0200
+++ new/android-file-transfer-linux-4.5/qt/mtpobjectsmodel.h 2025-05-15
00:28:05.000000000 +0200
@@ -101,9 +101,9 @@
mtp::ObjectId createDirectory(const QString &name, mtp::AssociationType
type = mtp::AssociationType::GenericFolder)
{ return createDirectory(_parentObjectId, name, type); }
- bool uploadFile(mtp::ObjectId parentObjectId, const QString &filePath,
QString filename = QString());
- bool uploadFile(const QString &filePath, QString filename = QString())
- { return uploadFile(_parentObjectId, filePath, filename); }
+ bool uploadFile(mtp::ObjectId parentObjectId, const QString &filePath,
QString filename = QString(), mtp::ObjectFormat format =
mtp::ObjectFormat::Any);
+ bool uploadFile(const QString &filePath, QString filename = QString(),
mtp::ObjectFormat format = mtp::ObjectFormat::Any)
+ { return uploadFile(_parentObjectId, filePath, filename, format); }
bool sendFile(const QString &filePath);
bool downloadFile(const QString &filePath, mtp::ObjectId objectId);
void rename(int idx, const QString &fileName);