@@ -964,6 +964,7 @@ void FlatpakShim::ApplicationInstall(
964964
965965 spdlog::info (" [FlatpakPlugin] Starting TWO-PHASE installation for: {}" , id);
966966
967+ operation_tracker_->TrackOperationStart (id, " install" );
967968 FlatpakTransaction* transaction =
968969 flatpak_transaction_new_for_installation (installation, nullptr , &error);
969970
@@ -1055,7 +1056,7 @@ void FlatpakShim::ApplicationInstall(
10551056
10561057 // run transaction in a detached thread
10571058 std::thread ([self, transaction_raw, callback, ref_name, remote_name,
1058- strand_ptr = strand_, installation_raw, found_ref_raw]() {
1059+ strand_ptr = strand_, installation_raw, found_ref_raw, id ]() {
10591060 pthread_setname_np (pthread_self (), " flatpak-install" );
10601061
10611062 GError* error = nullptr ;
@@ -1077,7 +1078,9 @@ void FlatpakShim::ApplicationInstall(
10771078 if (!success) {
10781079 spdlog::error (" [FlatpakPlugin] Phase 1 (dependencies) failed" );
10791080 asio::post (*strand_ptr, [self, callback, err_msg, transaction_raw,
1080- found_ref_raw, installation_raw]() {
1081+ found_ref_raw, installation_raw, id]() {
1082+ self->operation_tracker_ ->SendOperationFinish (id, " install" , false );
1083+
10811084 callback (ErrorOr<bool >(FlutterError (
10821085 " INSTALL_FAILED" , " Dependency installation failed: " + err_msg)));
10831086 g_object_unref (transaction_raw);
@@ -1208,7 +1211,8 @@ void FlatpakShim::ApplicationInstall(
12081211
12091212 if (!phase2_success) {
12101213 asio::post (*strand_ptr, [self, callback, phase2_err_msg, transaction_raw,
1211- found_ref_raw, installation_raw]() {
1214+ found_ref_raw, installation_raw, id]() {
1215+ self->operation_tracker_ ->SendOperationFinish (id, " install" , false );
12121216 callback (ErrorOr<bool >(FlutterError (
12131217 " INSTALL_FAILED" , " App installation failed: " + phase2_err_msg)));
12141218 g_object_unref (transaction_raw);
@@ -1247,17 +1251,19 @@ void FlatpakShim::ApplicationInstall(
12471251 }
12481252
12491253 asio::post (*strand_ptr, [self, callback, verified, ref_name,
1250- transaction_raw, found_ref_raw,
1251- installation_raw ]() {
1254+ transaction_raw, found_ref_raw, installation_raw,
1255+ id ]() {
12521256 if (verified) {
12531257 spdlog::info (
12541258 " [FlatpakPlugin] Application '{}' successfully installed and "
12551259 " verified" ,
12561260 ref_name);
1261+ self->operation_tracker_ ->SendOperationFinish (id, " install" , true );
12571262 callback (ErrorOr<bool >(true ));
12581263 } else {
12591264 spdlog::error (
12601265 " [FlatpakPlugin] Installation completed but verification failed" );
1266+ self->operation_tracker_ ->SendOperationFinish (id, " install" , false );
12611267 callback (ErrorOr<bool >(
12621268 FlutterError (" INSTALL_VERIFICATION_FAILED" ,
12631269 " Installation completed but app not found" )));
@@ -3981,38 +3987,72 @@ void FlatpakShim::OnOperationComplete(FlatpakTransaction* /* transaction */,
39813987 const char * ref = flatpak_transaction_operation_get_ref (operation);
39823988 auto type = flatpak_transaction_operation_get_operation_type (operation);
39833989
3984- std::string type_str =
3985- (type == FLATPAK_TRANSACTION_OPERATION_INSTALL ) ? " install" : " other" ;
3990+ std::string type_str;
3991+ switch (type) {
3992+ case FLATPAK_TRANSACTION_OPERATION_INSTALL :
3993+ type_str = " install" ;
3994+ break ;
3995+ case FLATPAK_TRANSACTION_OPERATION_UPDATE :
3996+ type_str = " update" ;
3997+ break ;
3998+ case FLATPAK_TRANSACTION_OPERATION_UNINSTALL :
3999+ type_str = " uninstall" ;
4000+ break ;
4001+ default :
4002+ type_str = " other" ;
4003+ break ;
4004+ }
4005+
4006+ std::string ref_str = ref ? std::string (ref) : std::string (" " );
39864007
39874008 if (ref) {
39884009 spdlog::info (
39894010 " [FlatpakPlugin] Operation completed: {} {} (result: {})" , type_str,
3990- std::string (ref) ,
4011+ ref_str ,
39914012 result == FLATPAK_TYPE_TRANSACTION_RESULT ? " SUCCESS" : " FAILED" );
39924013 }
39934014
4015+ std::string app_id;
4016+ auto active_ops = handler->operation_tracker_ ->GetActiveOperations ();
4017+
4018+ for (const auto & [id, op_info] : active_ops) {
4019+ if (ref_str.find (id) != std::string::npos || op_info.op_type == type_str) {
4020+ app_id = id;
4021+ handler->operation_tracker_ ->TrackOperationComplete (app_id, ref_str);
4022+ break ;
4023+ }
4024+ }
4025+
39944026 if (handler->strand_ ) {
3995- asio::post (
3996- *handler->strand_ ,
3997- [handler, ref = ref ? std::string (ref) : std::string (" " ),
3998- commit = commit ? std::string (commit) : std::string (" " ), result]() {
3999- try {
4000- flutter::EncodableMap OperationCompleteMap;
4001- OperationCompleteMap[flutter::EncodableValue (" type" )] =
4002- flutter::EncodableValue (" operation_complete" );
4003- OperationCompleteMap[flutter::EncodableValue (" operation_ref" )] =
4004- flutter::EncodableValue (ref);
4005- OperationCompleteMap[flutter::EncodableValue (" commit" )] =
4006- flutter::EncodableValue (commit);
4007- OperationCompleteMap[flutter::EncodableValue (" success" )] =
4008- flutter::EncodableValue (static_cast <int32_t >(result));
4009-
4010- handler->SendTransactionEvent (OperationCompleteMap);
4011- } catch (const std::exception& e) {
4012- spdlog::error (" [FlatpakPlugin] Error sending complete event: {}" ,
4013- e.what ());
4014- }
4015- });
4027+ asio::post (*handler->strand_ , [handler, ref_str,
4028+ commit = commit ? std::string (commit)
4029+ : std::string (" " ),
4030+ result, type_str, app_id]() {
4031+ try {
4032+ flutter::EncodableMap OperationCompleteMap;
4033+ OperationCompleteMap[flutter::EncodableValue (" type" )] =
4034+ flutter::EncodableValue (" operation_complete" );
4035+ OperationCompleteMap[flutter::EncodableValue (" operation_ref" )] =
4036+ flutter::EncodableValue (ref_str);
4037+ OperationCompleteMap[flutter::EncodableValue (" commit" )] =
4038+ flutter::EncodableValue (commit);
4039+ OperationCompleteMap[flutter::EncodableValue (" success" )] =
4040+ flutter::EncodableValue (static_cast <int32_t >(result));
4041+ OperationCompleteMap[flutter::EncodableValue (" operation_type" )] =
4042+ flutter::EncodableValue (type_str);
4043+
4044+ // Determine if this is the main app
4045+ bool is_main_app = ref_str.find (" app/" ) == 0 && !app_id.empty () &&
4046+ ref_str.find (app_id) != std::string::npos;
4047+ OperationCompleteMap[flutter::EncodableValue (" is_main_app" )] =
4048+ flutter::EncodableValue (is_main_app);
4049+
4050+ handler->SendTransactionEvent (OperationCompleteMap);
4051+ } catch (const std::exception& e) {
4052+ spdlog::error (" [FlatpakPlugin] Error sending complete event: {}" ,
4053+ e.what ());
4054+ }
4055+ });
40164056 }
40174057}
40184058
@@ -4067,6 +4107,7 @@ gboolean FlatpakShim::OnTransactionReady(FlatpakTransaction* transaction,
40674107
40684108 spdlog::info (" [FlatpakPlugin] Total operations to perform: {}" , total_ops);
40694109
4110+ std::string app_id;
40704111 flutter::EncodableList ops_list;
40714112 for (GList* l = operations; l != nullptr ; l = l->next ) {
40724113 auto * op = static_cast <FlatpakTransactionOperation*>(l->data );
@@ -4099,6 +4140,13 @@ gboolean FlatpakShim::OnTransactionReady(FlatpakTransaction* transaction,
40994140 std::string kind = " unknown" ;
41004141 if (ref_str.find (" app/" ) == 0 ) {
41014142 kind = " app" ;
4143+
4144+ // extract app to pass
4145+ size_t first_slash = ref_str.find (' /' ) + 1 ;
4146+ size_t second_slash = ref_str.find (' /' , first_slash);
4147+ if (second_slash != std::string::npos) {
4148+ app_id = ref_str.substr (first_slash, second_slash - first_slash);
4149+ }
41024150 } else if (ref_str.find (" runtime/" ) == 0 ) {
41034151 kind = " runtime" ;
41044152 }
@@ -4111,8 +4159,11 @@ gboolean FlatpakShim::OnTransactionReady(FlatpakTransaction* transaction,
41114159 ops_list.emplace_back (op_map);
41124160 }
41134161
4162+ if (app_id.empty ()) {
4163+ handler->operation_tracker_ ->UpdateTotalOperations (app_id, total_ops);
4164+ }
41144165 if (handler->strand_ ) {
4115- asio::post (*handler->strand_ , [handler, total_ops,
4166+ asio::post (*handler->strand_ , [handler, app_id, total_ops,
41164167 ops_list = std::move (ops_list)]() {
41174168 try {
41184169 flutter::EncodableMap ready_event;
@@ -4122,7 +4173,8 @@ gboolean FlatpakShim::OnTransactionReady(FlatpakTransaction* transaction,
41224173 flutter::EncodableValue (total_ops);
41234174 ready_event[flutter::EncodableValue (" operations" )] =
41244175 flutter::EncodableValue (ops_list);
4125-
4176+ ready_event[flutter::EncodableValue (" main_app_id" )] =
4177+ flutter::EncodableValue (app_id);
41264178 handler->SendTransactionEvent (ready_event);
41274179 } catch (const std::exception& e) {
41284180 spdlog::error (" [FlatpakPlugin] Error sending ready event: {}" ,
0 commit comments