44#include < QSaveFile>
55#include < QMessageBox>
66#include < QJsonObject>
7+ #include < QDir>
78#include < ui_imagemounter.h>
89#include < zip.h>
910#include " utils.h"
@@ -15,6 +16,7 @@ ImageMounter::ImageMounter(QWidget *parent)
1516 , m_downloadState(DOWNLOAD_STATE ::IDLE )
1617 , m_request(nullptr )
1718 , m_isCloseAction(false )
19+ , m_personalizedForceDownload(false )
1820{
1921 ui->setupUi (this );
2022 setWindowModality (Qt::WindowModality::WindowModal);
@@ -47,6 +49,9 @@ void ImageMounter::RefreshUI(bool fetchImages)
4749{
4850 QString OSVersion = DeviceBridge::Get ()->GetDeviceInfo ()[" ProductVersion" ].toString ();
4951 ui->OSVersion ->setText (OSVersion);
52+ const bool usePersonalized = m_personalizedImage.ShouldUsePersonalizedImage (OSVersion);
53+ UpdateOnlineSelectionUI (OSVersion);
54+
5055 auto mounted = DeviceBridge::Get ()->GetMountedImages ();
5156 if (mounted.length () > 0 )
5257 {
@@ -65,8 +70,9 @@ void ImageMounter::RefreshUI(bool fetchImages)
6570 {
6671 ui->onlineTab ->setEnabled (true );
6772 ui->tabWidget ->setCurrentWidget (ui->onlineTab );
68- if (fetchImages)
73+ if (fetchImages && !usePersonalized )
6974 {
75+ ui->repoBox ->clear ();
7076 for (const auto & owner : m_repoJson.object ().keys ())
7177 {
7278 ui->logField ->append (" Fetch from '" + m_repoJson[owner].toObject ()[" git_url" ].toString () + " '..." );
@@ -98,6 +104,10 @@ void ImageMounter::RefreshUI(bool fetchImages)
98104 });
99105 }
100106 }
107+ else if (usePersonalized)
108+ {
109+ ui->imageStatus ->setText (m_personalizedImage.UiHint ());
110+ }
101111 }
102112 else
103113 {
@@ -106,6 +116,38 @@ void ImageMounter::RefreshUI(bool fetchImages)
106116 }
107117}
108118
119+ void ImageMounter::UpdateOnlineSelectionUI (const QString& productVersion)
120+ {
121+ const bool usePersonalized = m_personalizedImage.ShouldUsePersonalizedImage (productVersion);
122+
123+ if (usePersonalized)
124+ {
125+ const bool oldRepoSignals = ui->repoBox ->blockSignals (true );
126+ ui->repoBox ->clear ();
127+ ui->repoBox ->addItem (m_personalizedImage.RepoOwner ());
128+ ui->repoBox ->setCurrentIndex (0 );
129+ ui->repoBox ->setEnabled (false );
130+ ui->repoBox ->blockSignals (oldRepoSignals);
131+
132+ ui->imageBox ->clear ();
133+ ui->imageBox ->addItem (m_personalizedImage.UiImageVersion ());
134+ ui->imageBox ->setCurrentIndex (0 );
135+ ui->imageBox ->setEnabled (false );
136+ ui->imageStatus ->setText (m_personalizedImage.UiHint ());
137+ }
138+ else
139+ {
140+ ui->repoBox ->setEnabled (true );
141+ ui->imageBox ->setEnabled (true );
142+ if (ui->repoBox ->count () == 1 && ui->repoBox ->itemText (0 ) == m_personalizedImage.RepoOwner ())
143+ {
144+ ui->repoBox ->clear ();
145+ ui->imageBox ->clear ();
146+ ui->imageStatus ->clear ();
147+ }
148+ }
149+ }
150+
109151void ImageMounter::OnRepoChanged (QString messages)
110152{
111153 ui->imageBox ->clear ();
@@ -157,11 +199,19 @@ void ImageMounter::DownloadImage(DOWNLOAD_TYPE downloadtype)
157199 m_downloadState = DOWNLOAD_STATE ::DOWNLOAD ;
158200 else if (downloadtype == DOWNLOAD_TYPE ::DIRECT_FILES )
159201 m_downloadState = DOWNLOAD_STATE ::FETCH ;
202+ else if (downloadtype == DOWNLOAD_TYPE ::PERSONALIZED_IMAGE )
203+ m_downloadState = DOWNLOAD_STATE ::DOWNLOAD ;
160204 }
161205
162206 switch (m_downloadState)
163207 {
164208 case DOWNLOAD_STATE ::FETCH :
209+ if (downloadtype == DOWNLOAD_TYPE ::PERSONALIZED_IMAGE )
210+ {
211+ m_downloadState = DOWNLOAD_STATE ::DOWNLOAD ;
212+ DownloadImage (downloadtype);
213+ break ;
214+ }
165215 ui->logField ->append (" Get image url from repository..." );
166216 m_request->Get (m_repoJson[repo_owner].toObject ()[" images" ].toObject ()[selected_version].toString (), [this , repo_owner, selected_version](QNetworkReply::NetworkError responseCode, QJsonDocument ResponseData){
167217 if (responseCode == QNetworkReply::NetworkError::NoError)
@@ -197,7 +247,21 @@ void ImageMounter::DownloadImage(DOWNLOAD_TYPE downloadtype)
197247 m_downloadUrls.remove (location);
198248 }
199249 }
200- ui->logField ->append (" Download " + (m_downloadout.endsWith (" .dmg" ) ? QString (" image" ) : " signature" ) + " file from repository..." );
250+ else if (downloadtype == DOWNLOAD_TYPE ::PERSONALIZED_IMAGE )
251+ {
252+ if (m_downloadUrls.isEmpty ())
253+ {
254+ ChangeDownloadState (DOWNLOAD_STATE ::DONE );
255+ break ;
256+ }
257+ const QString location = m_downloadUrls.firstKey ();
258+ m_downloadout = location;
259+ m_downloadurl = m_downloadUrls.take (location);
260+ }
261+ if (downloadtype == DOWNLOAD_TYPE ::PERSONALIZED_IMAGE )
262+ ui->logField ->append (" Download personalized file from repository..." );
263+ else
264+ ui->logField ->append (" Download " + (m_downloadout.endsWith (" .dmg" ) ? QString (" image" ) : " signature" ) + " file from repository..." );
201265 m_request->Download (m_downloadurl);
202266 break ;
203267 }
@@ -248,6 +312,27 @@ void ImageMounter::OnDownloadMountClicked()
248312 return ;
249313 }
250314
315+ const QString productVersion = DeviceBridge::Get ()->GetDeviceInfo ()[" ProductVersion" ].toString ();
316+ if (m_personalizedImage.ShouldUsePersonalizedImage (productVersion))
317+ {
318+ const QString productType = DeviceBridge::Get ()->GetDeviceInfo ()[" ProductType" ].toString ();
319+ bool productTypeFound = true ;
320+ if (m_personalizedImage.HasReadyImage (productType, productTypeFound))
321+ {
322+ DeviceBridge::Get ()->MountImage (m_personalizedImage.ImageDir (), " " );
323+ RefreshUI (false );
324+ return ;
325+ }
326+ if (!productTypeFound)
327+ {
328+ ui->logField ->append (" Product type is not in current personalized image list. Force download required..." );
329+ StartPersonalizedDownload (true );
330+ return ;
331+ }
332+ StartPersonalizedDownload (false );
333+ return ;
334+ }
335+
251336 if (ui->imageBox ->currentText ().isEmpty ())
252337 return ;
253338
@@ -283,6 +368,14 @@ void ImageMounter::OnDownloadResponse(SimpleRequest::RequestState req_state, int
283368
284369 case SimpleRequest::RequestState::STATE_FINISH :
285370 {
371+ if (error != QNetworkReply::NetworkError::NoError)
372+ {
373+ ui->logField ->append (" Download error: " + QVariant::fromValue (error).toString ());
374+ m_downloadState = DOWNLOAD_STATE ::IDLE ;
375+ m_downloadUrls.clear ();
376+ break ;
377+ }
378+
286379 if (m_downloadtype == DOWNLOAD_TYPE ::ARCHIVED_IMAGE )
287380 {
288381 ui->logField ->append (" Image Package downloaded." );
@@ -314,13 +407,85 @@ void ImageMounter::OnDownloadResponse(SimpleRequest::RequestState req_state, int
314407 file.commit ();
315408 ChangeDownloadState (m_downloadUrls.isEmpty () ? DOWNLOAD_STATE ::DONE : DOWNLOAD_STATE ::DOWNLOAD );
316409 }
410+ else if (m_downloadtype == DOWNLOAD_TYPE ::PERSONALIZED_IMAGE )
411+ {
412+ QFileInfo file_info (m_downloadout);
413+ ui->logField ->append (" Downloaded: " + file_info.fileName ());
414+ QDir ().mkpath (file_info.filePath ().remove (file_info.fileName ()));
415+ QSaveFile file (m_downloadout);
416+ if (!file.open (QIODevice::WriteOnly))
417+ {
418+ ui->logField ->append (" Error: Failed to write downloaded file: " + m_downloadout);
419+ m_downloadState = DOWNLOAD_STATE ::IDLE ;
420+ break ;
421+ }
422+ file.write (data.data (), data.size ());
423+ if (!file.commit ())
424+ {
425+ ui->logField ->append (" Error: Failed to commit downloaded file: " + m_downloadout);
426+ m_downloadState = DOWNLOAD_STATE ::IDLE ;
427+ break ;
428+ }
429+
430+ if (QFileInfo (m_downloadout).fileName () == QFileInfo (m_personalizedImage.ManifestPath ()).fileName ())
431+ {
432+ QString productType = DeviceBridge::Get ()->GetDeviceInfo ()[" ProductType" ].toString ();
433+ QString errorMessage;
434+ PersonalizedImage::PrepareResult prepareResult = m_personalizedImage.PrepareDownloads (
435+ productType, m_personalizedForceDownload, m_downloadUrls, errorMessage);
436+ if (prepareResult != PersonalizedImage::PrepareResult::OK )
437+ {
438+ if (prepareResult == PersonalizedImage::PrepareResult::RETRY_WITH_FORCE_DOWNLOAD )
439+ {
440+ StartPersonalizedDownload (true );
441+ break ;
442+ }
443+ if (!errorMessage.isEmpty ())
444+ ui->logField ->append (errorMessage);
445+ if (prepareResult == PersonalizedImage::PrepareResult::MODEL_NOT_FOUND )
446+ QMessageBox::critical (this , " Error" , errorMessage, QMessageBox::Ok);
447+ m_downloadState = DOWNLOAD_STATE ::IDLE ;
448+ break ;
449+ }
450+ }
451+ ChangeDownloadState (m_downloadUrls.isEmpty () ? DOWNLOAD_STATE ::DONE : DOWNLOAD_STATE ::DOWNLOAD );
452+ }
317453 break ;
318454 }
319455 case SimpleRequest::RequestState::STATE_ERROR :
320456 ui->logField ->append (" Download error: " + QVariant::fromValue (error).toString ());
457+ m_downloadState = DOWNLOAD_STATE ::IDLE ;
458+ m_downloadUrls.clear ();
321459 break ;
322460
323461 default :
324462 break ;
325463 }
326464}
465+
466+ void ImageMounter::StartPersonalizedDownload (bool forceDownload)
467+ {
468+ m_personalizedForceDownload = forceDownload;
469+ m_downloadtype = DOWNLOAD_TYPE ::PERSONALIZED_IMAGE ;
470+ m_downloadState = DOWNLOAD_STATE ::DOWNLOAD ;
471+ QString productType = DeviceBridge::Get ()->GetDeviceInfo ()[" ProductType" ].toString ();
472+ QString errorMessage;
473+ PersonalizedImage::PrepareResult prepareResult = m_personalizedImage.PrepareDownloads (
474+ productType, forceDownload, m_downloadUrls, errorMessage);
475+ if (prepareResult != PersonalizedImage::PrepareResult::OK )
476+ {
477+ if (prepareResult == PersonalizedImage::PrepareResult::RETRY_WITH_FORCE_DOWNLOAD )
478+ {
479+ StartPersonalizedDownload (true );
480+ return ;
481+ }
482+ if (!errorMessage.isEmpty ())
483+ ui->logField ->append (errorMessage);
484+ if (prepareResult == PersonalizedImage::PrepareResult::MODEL_NOT_FOUND )
485+ QMessageBox::critical (this , " Error" , errorMessage, QMessageBox::Ok);
486+ m_downloadState = DOWNLOAD_STATE ::IDLE ;
487+ return ;
488+ }
489+
490+ DownloadImage (DOWNLOAD_TYPE ::PERSONALIZED_IMAGE );
491+ }
0 commit comments