Closed Bug 830294 Opened 12 years ago Closed 12 years ago

Can't launch an app after canceling its update

Categories

(Core Graveyard :: DOM: Apps, defect)

ARM
Gonk (Firefox OS)
defect
Not set
normal

Tracking

(blocking-b2g:tef+, firefox19 wontfix, firefox20 wontfix, firefox21 fixed, b2g18 fixed, b2g18-v1.0.0 fixed)

VERIFIED FIXED
mozilla21
blocking-b2g tef+
Tracking Status
firefox19 --- wontfix
firefox20 --- wontfix
firefox21 --- fixed
b2g18 --- fixed
b2g18-v1.0.0 --- fixed

People

(Reporter: julienw, Assigned: fabrice)

References

Details

(Keywords: regression, Whiteboard: [triage:1/16])

Attachments

(2 files, 2 obsolete files)

STR: * install a big enough app (around 8MB is fine) whose you can trigger updates * trigger an update of this app * start the update this app * cancel the update * try to launch the app Expected: * the app is launching Actual: * nothing happens There is no meaningful logcat except we seems to get two errors from the platform: I/Gecko ( 1155): -*-*- Webapps.jsm : Cleanup: NETWORK_ERROR E/GeckoConsole( 1155): Content JS INFO at app://system.gaiamobile.org/js/updatable.js:101 in anonymous: downloadError event, error code is NETWORK_ERROR E/GeckoConsole( 1155): Content JS INFO at app://system.gaiamobile.org/js/updatable.js:101 in anonymous: downloadError event, error code is DOWNLOAD_CANCELED This could be another bug though.
blocking-b2g: tef? → tef+
Might be a regression. I thought this was working before...
Keywords: regression
Assignee: nobody → felash
I believe this is a DOM::Apps bug. The installState is reset to 'pending' when we get a downloaderror. This is obviously wrong because we basically have 2 cases of downloaderror: - the app is not installed yet, installState === 'pending' => no need to change it, it's still 'pending' - the app is installed, then installState === 'updating' => we should get it back to 'installed' imho. The installState is correctly set to 'updating' during the update. I'm continuing to investigate.
Component: Gaia::Homescreen → DOM: Apps
Product: Boot2Gecko → Core
I think I found the culprit. The error comes directly from the fact that we have two errors: the first one remove the saved value in AppInstallManager, so the second one can't find one, and use "pending" as a default. We have a line to prevent sending 2 errors in the install case, but it doesn't work in the update case because it checks for downloadAvailable. A patch is coming soon.
Attached patch patch v1 (obsolete) — Splinter Review
please tell me if you want that I remove the debug statements. also I may have not understood what the checks that I removed were for.
Attachment #702363 - Flags: review?(fabrice)
Comment on attachment 702363 [details] [diff] [review] patch v1 Review of attachment 702363 [details] [diff] [review]: ----------------------------------------------------------------- ::: dom/apps/src/Webapps.jsm @@ +21,5 @@ > Cu.import("resource://gre/modules/SystemMessagePermissionsChecker.jsm"); > Cu.import("resource://gre/modules/AppDownloadManager.jsm"); > > function debug(aMsg) { > + dump("-*-*- Webapps.jsm : " + aMsg + "\n"); re-comment. @@ +936,5 @@ > > // First of all, we check if the download is supposed to update an > // already installed application. > let isUpdate = (app.installState == "installed"); > + debug('startDownload - isUpdate = ' + isUpdate); remove @@ +1812,5 @@ > > // We avoid notifying the error to the DOM side if the app download > // was cancelled via cancelDownload, which already sends its own > // notification. > + if (!app.downloading) { Can you check if we can keep the !app.downloadAvailable here. I'm fine with removinf downloadSize since it comes from the manifest and may be incorrect.
Attachment #702363 - Flags: review?(fabrice) → feedback+
(In reply to Fabrice Desré [:fabrice] from comment #5) > > @@ +1812,5 @@ > > > > // We avoid notifying the error to the DOM side if the app download > > // was cancelled via cancelDownload, which already sends its own > > // notification. > > + if (!app.downloading) { > > Can you check if we can keep the !app.downloadAvailable here. I'm fine with > removinf downloadSize since it comes from the manifest and may be incorrect. That's actually the main problem: we're canceling an _update_ so we _do_ have a downloadAvailable property. If we keep this check here, then the bug comes back. I removed downloadSize more instinctively: I think we'd have it also in case of updates, but I'm not sure of that. Still I think |app.downloading| is sufficient here. Am I missing something ?
Attached patch patch v2Splinter Review
carry on fabrice's feedback+ who should I ask approval to ?
Attachment #702363 - Attachment is obsolete: true
Attachment #702413 - Flags: feedback+
feedback is not r+. I want to make sure we do the right sure for all the download cancel cases.
yep I understand that :) just wanted to ask for approval in advance.
Hi, AFAIK, maybe I'm wrong, being a tef+ you don't have to ask for approval, just receive a r+ (unless this is different for the backend bugs ;))
Francisco> ok, that's not what I thought but ok ;)
Also, approval applies to patches once they are ready to land.
Attachment #702413 - Flags: review?(fabrice)
Attached patch alternate patch (obsolete) — Splinter Review
Since what we want is explicitly now if we're called by cancelDownload, this patch does just that instead of relying of some fragile heuristic. Julien, does this fix the issue?
Attachment #702512 - Flags: feedback?(felash)
I'll try tomorrow (and I think it may work) but without trying I already think that this is not a right fix... Let me explain. The initial problem was that we were really getting 2 errors. So what we really want is _not_ sending 2 errors. Using |app.canceling| for that does not seem right. Testing |app.downloading| makes it really clear that we already handled this for this download. Or that we won't send an error if we already sent a success. Maybe testing the return value of AppInstallManager.get() is sufficient too... Also I wonder if we could not put a cleanup outside of downloadPackage and use it in |cancelDownload|. Anyway I'll try your patch tomorrow and see if it fixes this specific problem.
Except if you think that we might legitimately call |cleanup| with |app.downloading === false| but I couldn't find a place where we do that now. The fragile heuristic was what was here at first, with the checks to downloadSize and downloadAvailable, that you're also removing in your patch.
(In reply to Julien Wajsberg [:julienw] from comment #14) > The initial problem was that we were really getting 2 errors. So what we > really want is _not_ sending 2 errors. Using |app.canceling| for that does > not seem right. why? One error event was coming from cancelDownload() directly, and the other one from onStopRequest triggered by channel.cancel. What's wrong by making sure that we don't send the second one when we know that the channel is canceled by us explicitly, instead of going in onStopRequest because we finished the download? > Testing |app.downloading| makes it really clear that we already handled this > for this download. Or that we won't send an error if we already sent a > success. > > Maybe testing the return value of AppInstallManager.get() is sufficient > too... This is in gaia, right? I don't see how this relates to the current patches. > Also I wonder if we could not put a cleanup outside of downloadPackage and > use it in |cancelDownload|. You can't prevent onStopRequest from being called when the underlying channel is canceled. So I don't think this would work.
(In reply to Fabrice Desré [:fabrice] from comment #16) > (In reply to Julien Wajsberg [:julienw] from comment #14) > > > The initial problem was that we were really getting 2 errors. So what we > > really want is _not_ sending 2 errors. Using |app.canceling| for that does > > not seem right. > > why? One error event was coming from cancelDownload() directly, and the > other one from onStopRequest triggered by channel.cancel. What's wrong by > making sure that we don't send the second one when we know that the channel > is canceled by us explicitly, instead of going in onStopRequest because we > finished the download? We don't even know if the error is sent synchronously or asynchronously when we call |cancel| on the channel. And even if it will stay like this in the future. > > Testing |app.downloading| makes it really clear that we already handled this > > for this download. Or that we won't send an error if we already sent a > > success. You didn't comment this. > > > > Maybe testing the return value of AppInstallManager.get() is sufficient > > too... > > This is in gaia, right? I don't see how this relates to the current patches. Sorry, I was talking about |AppDownloadManager|... I'd say that if |AppDownloadManager.get(manifestURL)| is null, then something wrong happened. > > > Also I wonder if we could not put a cleanup outside of downloadPackage and > > use it in |cancelDownload|. > > You can't prevent onStopRequest from being called when the underlying > channel is canceled. So I don't think this would work. That was not my goal. I'd like to reduce the code where we modify |app.downloading| and having only one function sending errors would make it easier to not send them twice. But you still didn't say why my first patch does not work.
Comment on attachment 702512 [details] [diff] [review] alternate patch Anyway your patch does not fix the bug. So I guess the error is sent asynchronously when we cancel the download.
Attachment #702512 - Flags: feedback?(felash) → feedback-
Whiteboard: [triage:1/16]
I still think that it's better to rely on an explicit field indicating that we are stopping the download for a specific reason (canceling the download) than using the app state. We have too many corner cases and opportunities to regress that.
Attachment #702512 - Attachment is obsolete: true
Attachment #702923 - Flags: review?(ferjmoreno)
Comment on attachment 702923 [details] [diff] [review] alternate patch v2 Review of attachment 702923 [details] [diff] [review]: ----------------------------------------------------------------- Quick review as I can't test the patch right now. I agree that this feels like a safest way. ::: dom/apps/src/Webapps.jsm @@ +903,2 @@ > if (download.cacheUpdate) { > // Cancel hosted app download. Shouldn't we also set app.isCanceling for hosted apps?
Attachment #702923 - Flags: review?(ferjmoreno)
(In reply to Fernando Jiménez Moreno [:ferjm] from comment #20) > Shouldn't we also set app.isCanceling for hosted apps? No. We only need this flag for packaged apps to know in onStopRequest what causes the request to be stopped.
You are right. Thanks. r=me. Still couldn't test the patch though.
I will be able to test tomorrow. I understand the no regression argument even if I disagree for this specific case. But as you wish I can understand.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Just tried with latest b2g18, the bug is not fixed, sorry.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment on attachment 702923 [details] [diff] [review] alternate patch v2 And I still don't understand why this patch is safer. I fear a lot that isCanceling could stay set for some reason and makes thing worse.
I tried again with a full reseted phone, and I can't reproduce. So I put back "resolved fixed".
Status: REOPENED → RESOLVED
Closed: 12 years ago12 years ago
Resolution: --- → FIXED
Attachment #702413 - Flags: review?(fabrice)
Keywords: verifyme
QA Contact: jsmith
Target Milestone: --- → mozilla21
Verified using Julien's STR.
Status: RESOLVED → VERIFIED
Keywords: verifyme
Landed on mozilla-b2g18/gaia master prior to the 1/25 branching to mozilla-b2g18_v1_0_0/v1.0.0, updating status-b2g-v1.0.0 to fixed.
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: