<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>my tech blog &#187; stop updates</title>
	<atom:link href="http://billauer.se/blog/category/stop-updates/feed/" rel="self" type="application/rss+xml" />
	<link>https://billauer.se/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Thu, 12 Mar 2026 11:36:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Google Chrome: Stop that nagging on updates</title>
		<link>https://billauer.se/blog/2023/06/google-chrome-disable-update-popup/</link>
		<comments>https://billauer.se/blog/2023/06/google-chrome-disable-update-popup/#comments</comments>
		<pubDate>Sun, 11 Jun 2023 08:53:01 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[stop updates]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6892</guid>
		<description><![CDATA[I have Google Chrome installed on a Linux machine at /opt/google as root, so the browser can&#8217;t update itself automatically. Instead, it complains with this pop-up every time the browser is started: What I really like about this pop-up is the &#8220;you&#8217;re missing out&#8221; part. I get the same thing from the silly image gallery [...]]]></description>
			<content:encoded><![CDATA[<p>I have Google Chrome installed on a Linux machine at /opt/google as root, so the browser can&#8217;t update itself automatically. Instead, it complains with this pop-up every time the browser is started:</p>
<p><a href="https://billauer.se/blog/wp-content/uploads/2023/06/reinstall.jpg"><img class="aligncenter size-full wp-image-6893" title="Annoying Google Chrome update popup" src="https://billauer.se/blog/wp-content/uploads/2023/06/reinstall.jpg" alt="Annoying Google Chrome update popup" width="324" height="180" /></a></p>
<p>What I really like about this pop-up is the &#8220;you&#8217;re missing out&#8221; part. I get the same thing from the silly image gallery app on my Google Pixel phone.  This is Google trying to play on my (not so existent) FOMO.</p>
<p>It has been <a rel="noopener" href="https://stackoverflow.com/questions/27962454/disable-chrome-is-out-of-date-notification" target="_blank">suggested</a> to add the &#8211;simulate-outdated-no-au argument to the command line that executes Chrome. This works indeed. The common suggestion is however to do that on the shortcut that executes the browser. But that won&#8217;t cover the case when I run the browser from a shell. Something I do, every now and then. Don&#8217;t ask.</p>
<p>So a more sledge hammer solution is to edit the wrapper script:</p>
<pre>$ which google-chrome
/usr/bin/google-chrome</pre>
<p>So edit this file (as root), and change the last line from</p>
<pre>exec -a "$0" "$HERE/chrome" "$@"</pre>
<p>to</p>
<pre>exec -a "$0" "$HERE/chrome" <span class="punch">--simulate-outdated-no-au='Tue, 31 Dec 2099'</span> "$@"</pre>
<p>What does this mean, then? Well, according to the list of <a rel="noopener" href="https://chromium.googlesource.com/chromium/src/+/HEAD/chrome/common/chrome_switches.cc" target="_blank">Google Chrome switches</a>, this switch &#8220;simulates that current version is outdated and auto-update is off&#8221;. The date is referred to in the source&#8217;s <a rel="noopener" href="https://source.chromium.org/chromium/chromium/src/+/HEAD:chrome/browser/upgrade_detector/upgrade_detector_impl.cc" target="_blank">upgrade_detector_impl.cc</a>. Look there if you want to figure out why this works (I didn&#8217;t bother, actually).</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2023/06/google-chrome-disable-update-popup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Android 12: Preventing System Update (and that nagging popup window)</title>
		<link>https://billauer.se/blog/2022/08/android-turn-off-system-update/</link>
		<comments>https://billauer.se/blog/2022/08/android-turn-off-system-update/#comments</comments>
		<pubDate>Wed, 24 Aug 2022 06:58:22 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[stop updates]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6702</guid>
		<description><![CDATA[Android is not my profession I just want to say this first: I do completely different things for living. I&#8217;m not an Android expert, the last time I wrote code in Java was 20 years ago, and what&#8217;s written below is really not professional information nor advice. This is the stuff I found out while [...]]]></description>
			<content:encoded><![CDATA[<h3>Android is not my profession</h3>
<p>I just want to say this first: I do completely different things for living. I&#8217;m not an Android expert, the last time I wrote code in Java was 20 years ago, and what&#8217;s written below is really not professional information nor advice. This is the stuff I found out while trying to get my phone under control.</p>
<h3>When the phone doesn&#8217;t take &#8220;no&#8221; for an answer</h3>
<p>This is an increasing phenomenon: Software <a href="https://billauer.se/blog/category/stop-updates/" target="_blank">treating us like kids</a>, not asking what to do, not suggesting, but telling us what it&#8217;s about to do. Or just does it.</p>
<p>So let&#8217;s assume for a second that we&#8217;re grown-ups who can make our own decisions, and one of those decisions was not to update our phone&#8217;s software. Let&#8217;s leave the question if this is clever or not. It&#8217;s about who has control over the piece of electronics that you consider yours.</p>
<p>For the record, I would have been perfectly fine with having security patches applied frequently. The problem with updates is that there are &#8220;improvements&#8221; along with the security fixes, so there&#8217;s always something that suddenly doesn&#8217;t work after them. Because of a bug that will be fixed on the next update, of course.</p>
<p>The bad news is that to really stop the updates, you need a rooted phone, and if you haven&#8217;t done that yet, odds are that the price for doing that (i.e. <a title="Rooting a Google Pixel 6 Pro: An embedded Linux guy’s notes" href="https://billauer.se/blog/2022/06/root-google-pixel-pro/" target="_blank">wiping the phone completely</a>) is much worse than an update itself.</p>
<p>Plus you need adb installed and know how to work with it (I discuss adb briefly in <a title="adb, fastboot and ssh and other system stuff on Google Pixel 6 Pro" href="https://billauer.se/blog/2022/07/android-12-adb-fastboot/" target="_blank">this post</a>). Maybe that will change in the future, if there will be a simple app performing the necessary operations. Or maybe this will be integrated into the app that assists with rooting?</p>
<p>In case you want to get right to the point, jump to &#8220;Disabling activities&#8221; below. That&#8217;s where it says what to do.</p>
<p>All said below relates to Android 12, build SQ1D.220105.007 on a Google Pixel 6 Pro (and it quite appears like it&#8217;s going to stay that way).</p>
<h3>That nagging popup window</h3>
<p>After rooting the phone, there are two immediate actions that are supposed to turn off automatic system updates. Not that it helped much in my case, but here they are:</p>
<ul>
<li>Under Developer Options (which are enabled for unlocking anyhow). Turn off “Automatic system updates”.</li>
<li>Go to Settings &gt; Notifications &gt; App Notifications &gt; Google Play Settings and turn off System Update (to silence the “System update paused” notification)</li>
</ul>
<p>And after some time, the famous &#8220;Install update to keep device secure&#8221; popup appears. And again, and again:</p>
<p><a href="https://billauer.se/blog/wp-content/uploads/2022/06/install-update.jpg"><img class="aligncenter size-medium wp-image-6672" style="display: block; margin-left: auto; margin-right: auto;" title="Screenshot of popup: &quot;Install update to keep device secure&quot;" src="https://billauer.se/blog/wp-content/uploads/2022/06/install-update-300x267.jpg" alt="Screenshot of popup: &quot;Install update to keep device secure&quot;" width="300" height="267" /></a></p>
<p>Which is a nuisance, and there&#8217;s always the risk of mistakenly tap &#8220;Install now&#8221;. But then it escalated to &#8220;Install now to control when your device updates&#8221;:</p>
<p><a href="https://billauer.se/blog/wp-content/uploads/2022/08/install-now.jpg"><img class="aligncenter size-medium wp-image-6703" title="Screenshot of popup: &quot;Install now to control when your device updates&quot;" src="https://billauer.se/blog/wp-content/uploads/2022/08/install-now-213x300.jpg" alt="Screenshot of popup: &quot;Install now to control when your device updates&quot;" width="213" height="300" /></a></p>
<p>This is a simple ultimatum, made by the machine I&#8217;m supposed to own: Either you do the update yourself, or I do it anyhow. And if that turns out to blow up your phone bill, your problem. How cute.</p>
<h3>Who&#8217;s behind the popup window?</h3>
<p>The first step is to figure out what package initiates the request for an update.</p>
<p>But even before that, it&#8217;s necessary to understand how Intents and Activities work together to put things on the screen.</p>
<p><a rel="noopener" href="https://developer.android.com/guide/components/activities/intro-activities" target="_blank">This page</a> explains Activities and their relations with Intents, and <a rel="noopener" href="https://developer.android.com/training/basics/firstapp/starting-activity" target="_blank">this page</a> shows a simple code example on this matter.</p>
<p>Activities are (primarily?) foreground tasks that represent a piece of GUI interaction, that are always visible on the screen, and they get paused as soon as the user chooses something else on the GUI.</p>
<p>Then there&#8217;s a thing called <a rel="noopener" href="https://developer.android.com/reference/android/content/Intent" target="_blank">Intent</a> in Android, which is an abstraction for performing a certain operation. This allows any software component to ask for a certain task to be completed, and that translates into an Activity. So the idea is that any software components requests an operation as an Intent, and some other software component (or itself) listens for these requests, and carries out the matching Activity in response.</p>
<p>For example, WhatsApp (like many other apps) has an Intent published for sharing files (ACTION_SEND), so when any application wants to share something, it opens a menu of candidates for sharing (which is all Intents published for that purpose), and when the user selects WhatsApp to share with, the application calls the Activity that is registered by WhatsApp for that Intent. Which file to share is given as an &#8220;extra&#8221; to the Intent (which simply means that the call has an argument). Note that what actually happens is that WhatApp takes over the screen completely, which is exactly the idea behind Activities.</p>
<p>Now some hands-on. When the popup appears, go</p>
<pre>$ adb shell dumpsys window windows &gt; dump.txt</pre>
<p>That produces a lot of output, but there was this segment:</p>
<pre>  Window #10 Window{28d0746 u0 <span class="punch">com.google.android.gms/com.google.android.gms.update.phone.PopupDialog</span>}:
    mDisplayId=0 rootTaskId=26 mSession=Session{55a992b 9996:u0a10146} mClient=android.os.BinderProxy@95ec721
    mOwnerUid=10146 showForAllUsers=false package=com.google.android.gms appop=NONE
    mAttrs={(0,0)(wrapxwrap) sim={adjust=pan forwardNavigation} ty=BASE_APPLICATION fmt=TRANSLUCENT wanim=0x10302f4 surfaceInsets=Rect(112, 112 - 112, 112)
      fl=DIM_BEHIND SPLIT_TOUCH HARDWARE_ACCELERATED
      pfl=USE_BLAST INSET_PARENT_FRAME_BY_IME
      bhv=DEFAULT
      fitTypes=STATUS_BARS NAVIGATION_BARS CAPTION_BAR}
    Requested w=1120 h=1589 mLayoutSeq=4826
    mBaseLayer=21000 mSubLayer=0    mToken=ActivityRecord{577992f u0 com.google.android.gms/.update.phone.PopupDialog t26}
    mActivityRecord=ActivityRecord{577992f u0 com.google.android.gms/.update.phone.PopupDialog t26}
    mAppDied=false    drawnStateEvaluated=true    mightAffectAllDrawn=true
    mViewVisibility=0x0 mHaveFrame=true mObscured=false
    mGivenContentInsets=[0,0][0,0] mGivenVisibleInsets=[0,0][0,0]
    mFullConfiguration={1.0 425mcc1mnc [en_US,iw_IL,ar_PS] ldltr sw411dp w411dp h834dp 560dpi nrml long hdr widecg port night finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1440, 3120) mAppBounds=Rect(0, 130 - 1440, 3064) mMaxBounds=Rect(0, 0 - 1440, 3120) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} as.2 s.1 fontWeightAdjustment=0}
    mLastReportedConfiguration={1.0 425mcc1mnc [en_US,iw_IL,ar_PS] ldltr sw411dp w411dp h834dp 560dpi nrml long hdr widecg port night finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1440, 3120) mAppBounds=Rect(0, 130 - 1440, 3064) mMaxBounds=Rect(0, 0 - 1440, 3120) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} as.2 s.1 fontWeightAdjustment=0}
    mHasSurface=true isReadyForDisplay()=true mWindowRemovalAllowed=false
    Frames: containing=[0,145][1440,3064] parent=[0,145][1440,3064] display=[0,145][1440,3064]
    mFrame=[160,810][1280,2399] last=[160,810][1280,2399]
     surface=[112,112][112,112]
    WindowStateAnimator{9e9cbdf com.google.android.gms/com.google.android.gms.update.phone.PopupDialog}:
      mSurface=Surface(name=<span class="punch">com.google.android.gms/com.google.android.gms.update.phone.PopupDialog</span>)/@0x223f02c
      Surface: shown=true layer=0 alpha=1.0 rect=(0.0,0.0)  transform=(1.0, 0.0, 0.0, 1.0)
      mDrawState=HAS_DRAWN       mLastHidden=false
      mEnterAnimationPending=false      mSystemDecorRect=[0,0][0,0]
    mForceSeamlesslyRotate=false seamlesslyRotate: pending=null finishedFrameNumber=0
    mDrawLock=WakeLock{a82daf5 held=false, refCount=5}
    isOnScreen=true
    isVisible=true</pre>
<p>Also, in the output of</p>
<pre>$ adb shell dumpsys &gt; all.txt</pre>
<p>there was a much more to-the-point section saying (pretty much at the beginning of this huge file):</p>
<pre>Display 4619827677550801152 HWC layers:
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 Layer name
           Z |  Window Type |  Comp Type |  Transform |   Disp Frame (LTRB) |          Source Crop (LTRB) |     Frame Rate (Explicit) (Seamlessness) [Focused]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 Wallpaper BBQ wrapper#0
  rel      0 |         2013 |     DEVICE |          0 |    0    0 1440 3120 |   65.0  142.0 1375.0 2978.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 com.google.android.apps.nexuslaunche[...]exuslauncher.NexusLauncherActivity#0
  rel      0 |            1 |     DEVICE |          0 |    0    0 1440 3120 |    0.0    0.0 1440.0 3120.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 Dim Layer for - WindowedMagnification:0:31#0
  rel     -1 |            0 |     DEVICE |          0 |    0    0 1440 3120 |    0.0    0.0    0.0    0.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 com.google.android.gms/com.google.android.gms.update.phone.PopupDialog#0
  rel      0 |            1 |     DEVICE |          0 |   48  698 1392 2511 |    0.0    0.0 1344.0 1813.0 |                                              [*]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 StatusBar#0
  rel      0 |         2000 |     DEVICE |          0 |    0    0 1440  145 |    0.0    0.0 1440.0  145.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 NavigationBar0#0
  rel      0 |         2019 |     DEVICE |          0 |    0 2952 1440 3120 |    0.0    0.0 1440.0  168.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 ScreenDecorOverlay#0
  rel      0 |         2024 |     DEVICE |          0 |    0    0 1440  176 |    0.0    0.0 1440.0  176.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------
 ScreenDecorOverlayBottom#0
  rel      0 |         2024 |     DEVICE |          0 |    0 2944 1440 3120 |    0.0    0.0 1440.0  176.0 |                                              [ ]
---------------------------------------------------------------------------------------------------------------------------------------------------------------</pre>
<p>This is much better, because the window in focus is clearly marked. No need to guess.</p>
<p>Another place to look at is</p>
<pre>$ adb shell dumpsys activity recents &gt; recent.txt</pre>
<p>Where it said:</p>
<pre>  * Recent #0: Task{51b5cb8 #26 type=standard A=10146:com.google.android.gms U=0 visible=true mode=fullscreen translucent=true sz=1}
    userId=0 effectiveUid=u0a146 mCallingUid=u0a146 mUserSetupComplete=true mCallingPackage=com.google.android.gms mCallingFeatureId=com.google.android.gms.ota_base
    affinity=10146:com.google.android.gms
    intent={act=<span class="punch">android.settings.SYSTEM_UPDATE_COMPLETE</span> flg=0x10848000 pkg=com.google.android.gms cmp=com.google.android.gms/.update.phone.PopupDialog}
    mActivityComponent=com.google.android.gms/.update.phone.PopupDialog
    rootWasReset=false mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
    Activities=[ActivityRecord{577992f u0 <span class="punch">com.google.android.gms/.update.phone.PopupDialog</span> t26}]
    askedCompatMode=false inRecents=true isAvailable=true
    taskId=26 rootTaskId=26
    hasChildPipActivity=false
    mHasBeenVisible=true
    mResizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION mSupportsPictureInPicture=false isResizeable=true
    lastActiveTime=232790582 (inactive for 23s)</pre>
<p>This is interesting, as it says which Intent and Activity stand behind the popup, just by asking what the last Activity requests were. Even more important, if the popup was dismissed or disappeared for any other reason, it can still be found here.</p>
<p>So no doubt, it&#8217;s com.google.android.gms that stands behind this popup. That&#8217;s Google Mobile Service, and it&#8217;s a package that is responsible for a whole lot. So disabling it is out of the question (and uninstalling impossible).</p>
<p>Under the section &#8220;ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)&#8221; there was</p>
<pre>    #8: PendingIntentRecord{50a35f1 com.google.android.gms/com.google.android.gms.ota_base broadcastIntent}
      uid=10146 packageName=com.google.android.gms featureId=com.google.android.gms.ota_base type=broadcastIntent flags=0x2000000
      requestIntent=act=com.google.android.chimera.IntentOperation.TARGETED_INTENT dat=chimeraio:/com.google.android.gms.chimera.GmsIntentOperationService/com.google.android.gms.update.INSTALL_UPDATE pkg=com.google.android.gms (has extras)
      sent=true canceled=false</pre>
<p>which I suppose indicates that com.google.android.gms has requested to run its own .update.INSTALL_UPDATE at a later stage. In other words, this is the indication of the recurring request to run the INSTALL_UPDATE intent.</p>
<h3>Disabling activities</h3>
<p>The trick to disable the popup, as well as the update itself, is to disable certain Android Activities. This is inspired by <a rel="noopener" href="https://forum.xda-developers.com/t/how-to-stop-ota-update-on-nougat.3588731/" target="_blank">this post in XDA forums</a>.</p>
<p>First, find all activities in the system:</p>
<pre>$ adb shell dumpsys package &gt; dumpsys-package.txt</pre>
<p>Then look for those specific to the package:</p>
<pre>$ grep com.google.android.gms dumpsys-package.txt | less</pre>
<p>Actually, one can narrow it down even more to those having the &#8220;.update.&#8221; substring:</p>
<pre>$ grep com.google.android.gms dumpsys-package.txt | grep -i \\.update\\. | less</pre>
<p>And eventually, disable what appears to be relevant activities (adb shell commands as root):</p>
<pre># pm disable com.google.android.gms/.update.SystemUpdateActivity
# pm disable com.google.android.gms/.update.SystemUpdateService
# pm disable com.google.android.gms/.update.SystemUpdateGcmTaskService</pre>
<p>And possibly also the popup itself:</p>
<pre># pm disable com.google.android.gms/.update.phone.PopupDialog
# pm disable com.google.android.gms/.update.OtaSuggestionActivity</pre>
<p>I&#8217;m not sure if all of these are necessary. The list might change across different versions of Android.</p>
<p>For each command, pm responds with a confirmation, e.g.</p>
<pre># <strong>pm disable com.google.android.gms/.update.SystemUpdateActivity</strong>
Component {com.google.android.gms/com.google.android.gms.update.SystemUpdateActivity} new state: disabled</pre>
<p>And then reboot (not sure it&#8217;s necessary, but often &#8220;disable&#8221; doesn&#8217;t mean &#8220;stop&#8221;).</p>
<p>Are the changes in effect? Make a dump of the package:</p>
<pre>$ adb shell pm dump com.google.android.gms &gt; gms-dump.txt</pre>
<p>and search for e.g. SystemUpdateActivity in the file. These features should appear under &#8220;disabledComponents:&#8221;.</p>
<p>However running &#8220;adb shell dumpsys activity intents&#8221;, it&#8217;s evident that the com.google.android.gms.update.INSTALL_UPDATE intent is still active. So this Intent will still be requested in the future. See below what happens with that.</p>
<p>So it&#8217;s quite clear that the popup can be disabled, but it&#8217;s less obvious what happens if the system wants to update itself when the relevant activity is disabled. Will it or will it not prevent the update? The proof is in the pudding.</p>
<h3>So here&#8217;s the pudding</h3>
<p>To begin with, the phone didn&#8217;t bug me again on updating, and neither has it done anything in that direction. Regardless (or not), there&#8217;s no problem updating all apps on the phone, and neither does it provoke any unwanted stuff. I&#8217;ve seen some speculations on the web, that System Update was somehow related to Google Play, and given my experience, I don&#8217;t think this is the case.</p>
<p>So disabling the Activities did the trick. It&#8217;s also possible to see exactly what happened by looking at the output of</p>
<pre>$ adb shell logcat -d &gt; all-log.txt</pre>
<p>where it says this somewhere around the time it should have started messing around:</p>
<pre>08-22 18:39:19.063  1461  1972 I ActivityTaskManager: START u0 {act=android.settings.<span class="punch">SYSTEM_UPDATE_COMPLETE</span> flg=0x10048000 pkg=com.google.android.gms (has extras)} from uid 10146
--------- beginning of crash
08-22 18:39:19.069  2838  7279 E AndroidRuntime: FATAL EXCEPTION: [com.google.android.gms.chimera.container.intentoperation.GmsIntentOperationChimeraService-Executor] idle
08-22 18:39:19.069  2838  7279 E AndroidRuntime: Process: com.google.android.gms, PID: 2838
08-22 18:39:19.069  2838  7279 E AndroidRuntime: android.content.<span class="punch">ActivityNotFoundException</span>: No Activity found to handle Intent { act=android.settings.SYSTEM_UPDATE_COMPLETE flg=0x10048000 pkg=com.google.android.gms (has extras) }
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2087)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1747)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at android.app.ContextImpl.startActivity(ContextImpl.java:1085)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at android.app.ContextImpl.startActivity(ContextImpl.java:1056)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at android.content.ContextWrapper.startActivity(ContextWrapper.java:411)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at com.google.android.gms.update.reminder.UpdateReminderDialogIntentOperation.a(:com.google.android.gms@222615044@22.26.15 (190400-461192076):67)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at com.google.android.gms.update.reminder.UpdateReminderDialogIntentOperation.onHandleIntent(:com.google.android.gms@222615044@22.26.15 (190400-461192076):10)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at com.google.android.chimera.IntentOperation.onHandleIntent(:com.google.android.gms@222615044@22.26.15 (190400-461192076):2)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at uzr.onHandleIntent(:com.google.android.gms@222615044@22.26.15 (190400-461192076):4)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at ffi.run(:com.google.android.gms@222615044@22.26.15 (190400-461192076):3)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at ffh.run(:com.google.android.gms@222615044@22.26.15 (190400-461192076):11)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at cfvf.run(:com.google.android.gms@222615044@22.26.15 (190400-461192076):2)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
08-22 18:39:19.069  2838  7279 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:1012)
08-22 18:39:19.092  1461  4210 I DropBoxManagerService: add tag=system_app_crash isTagEnabled=true flags=0x2
08-22 18:39:19.094  1461  1552 W BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.DROPBOX_ENTRY_ADDED flg=0x10 (has extras) } to com.google.android.gms/.stats.service.DropBoxEntryAddedReceiver
08-22 18:39:19.094  1461  1552 W BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.DROPBOX_ENTRY_ADDED flg=0x10 (has extras) } to com.google.android.gms/.chimera.GmsIntentOperationService$PersistentTrustedReceiver
08-22 18:39:19.270  1461  4215 I ActivityManager: <span class="punch">Process com.google.android.gms (pid 2838) has died: fg  SVC</span>
08-22 18:39:19.271  1461  4215 W ActivityManager: <span class="punch">Scheduling restart of crashed service com.google.android.gms/.chimera.GmsIntentOperationService</span> in 1000ms for start-requested
08-22 18:39:20.273  1461  1552 D CompatibilityChangeReporter: Compat change id reported: 135634846; UID 10146; state: DISABLED
08-22 18:39:20.274  1461  1552 D CompatibilityChangeReporter: Compat change id reported: 177438394; UID 10146; state: DISABLED
08-22 18:39:20.274  1461  1552 D CompatibilityChangeReporter: Compat change id reported: 135772972; UID 10146; state: DISABLED
08-22 18:39:20.274  1461  1552 D CompatibilityChangeReporter: Compat change id reported: 135754954; UID 10146; state: ENABLED
08-22 18:39:20.275  1461  1553 D CompatibilityChangeReporter: Compat change id reported: 143937733; UID 10146; state: ENABLED
08-22 18:39:20.296  1461  1553 I ActivityManager: <span class="punch">Start proc 7305:com.google.android.gms/u0a146</span> for service {com.google.android.gms/com.google.android.gms.chimera.GmsIntentOperationService}</pre>
<p>Clearly, disabling the Activities made them ineligible for handling the SYSTEM_UPDATE_COMPLETE Intent, so an ActivityNotFoundException was thrown. Surprisingly enough, this exception wasn&#8217;t caught, so the com.google.android.gms process simply died and was quickly restarted by the system.</p>
<p>I also found these later on:</p>
<pre>08-24 07:20:00.085 16126 25006 I SystemUpdate: [Execution,InstallationIntentOperation] Received intent: Intent { act=com.google.android.gms.update.INSTALL_UPDATE cat=[targeted_intent_op_prefix:.update.execution.InstallationIntentOperation] pkg=com.google.android.gms cmp=com.google.android.gms/.chimera.GmsIntentOperationService }.
08-24 07:20:00.114 16126 25006 W GmsTaskScheduler: com.google.android.gms.update.SystemUpdateGcmTaskService is not available. This may cause the task to be lost.
08-24 07:20:00.118 16126 25006 W GmsTaskScheduler: com.google.android.gms.update.SystemUpdateGcmTaskService is not available. This may cause the task to be lost.
08-24 07:20:00.119 16126 25006 W GmsTaskScheduler: com.google.android.gms.update.SystemUpdateGcmTaskService is not available. This may cause the task to be lost.

<span class="yadayada">[ ... ]</span>

08-24 07:20:00.198 16126 25006 I SystemUpdate: [Control,InstallationControl] Installation progress updated to (0x413, -1.000).
08-24 07:20:00.273 16126 25006 I SystemUpdate: [Control,ChimeraGcmTaskService] Scheduling task: DeviceIdle.
08-24 07:20:00.273 16126 25006 W GmsTaskScheduler: com.google.android.gms.update.SystemUpdateGcmTaskService is not available. This may cause the task to be lost.
08-24 07:20:00.274 16126 25006 I SystemUpdate: [Execution,ExecutionManager] Action streaming-apply executed for 0.17 seconds.
08-24 07:20:00.283 16126 25006 I SystemUpdate: [Execution,ExecutionManager] Action fixed-delay-execution executed for 0.01 seconds.</pre>
<p>Bottom line: Disabling the activity causes the GMS service to die and restart every time it thinks about updating the system and/or nagging about it. So it won&#8217;t happen. Mission accomplished.</p>
<p>Actually, I&#8217;m not sure it&#8217;s possible to update the phone now, even if I wanted to.</p>
<p>It wasn&#8217;t obvious that this would work. Disabling the activity could have canceled just the GUI part of the update process. But it did.</p>
<p>It would have been more elegant to add another package, that supplies an Activity for the SYSTEM_UPDATE_COMPLETE Intent, that runs instead of the original, disabled one. This would have avoided this recurring crash. I don&#8217;t know if this is possible though.</p>
<p>Or even better, to disable the recurring call to this Intent. Ideas are welcome.</p>
<h3>Or did it really work?</h3>
<p>A couple of months later, and I noted something that looked like a huge download. Using &#8220;top&#8221; on &#8220;adb shell&#8221; revealed that the <a href="https://android.googlesource.com/platform/system/update_engine/" target="_blank">update_engine</a> consumed some 60% CPU. Using logcat as above revealed several entries like these:</p>
<pre>10-29 20:43:38.677 18745 24156 I SystemUpdate: [Control,InstallationControl] Installation progress updated to (0x111, 0.704).
10-29 20:43:38.717 18745 24156 I SystemUpdate: [Control,InstallationControl] Update engine status updated to 0x003.
10-29 20:43:38.832  1106  1106 I update_engine: [INFO:delta_performer.cc(115)] Completed 1691/2292 operations (73%), 1429588024/2027780609 bytes downloaded (70%), overall progress 71%</pre>
<p>So there is definitely some download activity going on. The question is what will happen when it reaches 100%. And even more important, if there&#8217;s a way to prevent this from happening.</p>
<p>And maybe I&#8217;m just a bit too uptight. Using (as root)</p>
<pre># find /mnt/installer/0/emulated/ -cmin -1 2&gt;/dev/null</pre>
<p>to find newly update files, it appears like the activity is in /mnt/installer/0/emulated/0/Android/data/com.google.android.googlequicksearchbox/files/download_cache, and that the downloaded files are like soda-en-US-v7025-3.zip, which appears to be <a href="https://android.stackexchange.com/questions/246369/zip-files-with-name-soda-en-us-v1001-1-zip-appearing-on-their-own-on-android-1" target="_blank">Speech On Device Access</a>. And I&#8217;m fine with that.</p>
<h3>Or did it really work II?</h3>
<p>I owe this part to Namelesswonder&#8217;s very useful comment below. Indeed, the logs are at /data/misc/update_engine_log/, and there are indeed some files there from October, which is when there was some update activity. The progress of the download, in percents and bytes, is written in these logs.</p>
<p>The first log has an interesting row:</p>
<pre>[1003/115142.712102] [INFO:main.cc(55)] A/B Update Engine starting
[1003/115142.720019] [INFO:boot_control_android.cc(68)] Loaded boot control hidl hal.
[1003/115142.738330] [INFO:update_attempter_android.cc(1070)] <span class="punch">Scheduling CleanupPreviousUpdateAction.</span>
[1003/115142.747361] [INFO:action_processor.cc(51)] ActionProcessor: starting CleanupPreviousUpdateAction</pre>
<p>Any idea how to schedule CleanupPreviousUpdateAction manually? Sounds like fun to me.</p>
<p>The logs also name the URL of the downloaded package, https://ota.googlezip.net/packages/ota-api/package/d895ce906129e5138db6141ec735740cd1cd1b07.zip which is about 1.9 GB, so it&#8217;s definitely a full-blown update.</p>
<p>What is even more interesting from the logs is this line, which appears every time before starting or resuming an OTA download:</p>
<pre>[1029/201649.018352] [INFO:delta_performer.cc(1009)] Verifying using certificates: /system/etc/security/otacerts.zip</pre>
<p>It&#8217;s a ZIP file, which contains a single, bare-bone self-signed certificate in PEM format, which contains no fancy information.</p>
<p>It seems quite obvious that this certificate is used to authenticate the update file. What happens if this file is absent? No authentication, no update. Probably no download. So the immediate idea is to rename this file to something else. But it&#8217;s not that easy:</p>
<pre># mv otacerts.zip renamed-otacerts.zip
mv: bad 'otacerts.zip': Read-only file system</pre>
<p>That&#8217;s true. /system/etc/security/ is on the root file system, and that happens to be a read-only one. But it&#8217;s a good candidate for a Magisk override, I guess.</p>
<p>Another thing that was mentioned in the said comment, is that the data goes to /data/ota_package/. That&#8217;s interesting, because in my system this directory is nearly empty, but the files&#8217; modification timestamp is slightly before I neutralized the update activities, as mentioned above.</p>
<p>So it appears like the downloaded data goes directly into a raw partition, rather than a file.</p>
<p>There&#8217;s also /data/misc/update_engine/prefs/, which contains the current status of the download and other metadata. For example, update-state-next-data-offset apparently says how much has been downloaded already. What happens if this directory is nonexistent? Is it recreated, or is this too much for the updater to take?</p>
<p>As an initial approach, I renamed the &#8220;prefs&#8221; directory to &#8220;renamed-prefs&#8221;. A few days later, a new &#8220;prefs&#8221; directory was created, with just boot-id, previous-slot and previous-version files. Their timestamp matched a new log entry in update_engine_log/, which consisted of a CleanupPreviousUpdateAction. So apparently, the previous download was aborted and restarted.</p>
<p>So this time I renamed update_engine into something else, and added update_engine as a plain file. Before doing this, I tried to make the directory unreadable, but as root it&#8217;s accessible anyhow (in Android, not a normal Linux system). So the idea is to make it a non-directory, and maybe that will cause an irrecoverable failure.</p>
<p><span style="text-decoration: underline;">Update 8.12.22</span>: Nope, that didn&#8217;t help. A new log entry appeared in update_engine_log/, not a single word about the failure to create update_engine/prefs/, but a whole lot of rows indicating the download&#8217;s progress. /data/misc/update_engine remained as a plain file, so nothing could be stored in the correct place for the prefs/ subdirectory. I failed to find files with the names of those that are usually in prefs/ anywhere in the filesystem, so I wonder how the download will resume after it&#8217;s interrupted.</p>
<p><span style="text-decoration: underline;">Update 8.5.24</span>: For a long time, the phone hasn&#8217;t attempted to upgrade itself. Maybe because of the version gap. So in the end (?), I got some peace and quiet.</p>
<h3>Maybe this is related?</h3>
<p>/etc/init/ contains the services to be run during boot. One of them is called update_engine.rc, and another update_verifier.rc. Maybe delete these two files? I haven&#8217;t done this, because why mess with a phone that is OK now?</p>
<hr />
<p><em>These are a few unrelated topics, which didn&#8217;t turn out helpful. So they&#8217;re left here, just in case.</em></p>
<h3>Downloading the source</h3>
<p>I had the idea of grabbing the sources for the GMS package, and see what went on there.</p>
<p>The list of Git repos is <a rel="noopener" href="https://android.googlesource.com/" target="_blank">here</a> (or the GitHub  mirror <a href="https://github.com/aosp-mirror" target="_blank">here</a>). I went for the <a rel="noopener" href="https://android.googlesource.com/platform/frameworks/base/" target="_blank">this one</a>:</p>
<pre>git clone https://android.googlesource.com/platform/frameworks/base</pre>
<p>or the GitHub mirror:</p>
<pre>git clone https://github.com/aosp-mirror/platform_frameworks_base.git</pre>
<p>however this doesn&#8217;t seem to include the relevant parts.</p>
<h3>Permissions</h3>
<p>Another approach I had in mind was to turn off the permission to make a system update. I don&#8217;t know if there actually is such.</p>
<p>Android&#8217;s <a rel="noopener" href="https://developer.android.com/training/permissions/usage-notes" target="_blank">permission system</a> allows granting and revoking permissions as required. Just typing &#8220;pm&#8221; (package manager) on adb shell returns help information</p>
<p>To get a list of all permissions in the system:</p>
<pre>$ adb shell pm list permissions -g &gt; list.txt</pre>
<p>But that covers everything, so the trick is to search for the appearances of the specific package of interest. Something like</p>
<pre>$ grep com.google.android.gms list.txt | sort | less</pre>
<p>and look at that list. I didn&#8217;t anything that appears to related to system update.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2022/08/android-turn-off-system-update/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Thunderbird: Upgrade notes</title>
		<link>https://billauer.se/blog/2022/06/thunderbird-installation-oauth2/</link>
		<comments>https://billauer.se/blog/2022/06/thunderbird-installation-oauth2/#comments</comments>
		<pubDate>Fri, 10 Jun 2022 15:16:22 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[email]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[stop updates]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=6618</guid>
		<description><![CDATA[Introduction These are my notes as I upgraded Thunderbird from version 3.0.7 (released September 2010) to 91.10.0 on Linux Mint 19. That&#8217;s more than a ten year&#8217;s gap, which says something about what I think about upgrading software (which was somewhat justified, given the rubbish issues that arose, as detailed below). What eventually forced me [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>These are my notes as I upgraded Thunderbird from version 3.0.7 (released September 2010) to 91.10.0 on Linux Mint 19. That&#8217;s more than a ten year&#8217;s gap, which says something about what I think about upgrading software (which was somewhat justified, given the rubbish issues that arose, as detailed below). What eventually forced me to do this was the need to support OAuth2 in order to send emails through Google&#8217;s Gmail server (supported <a rel="noopener" href="https://support.mozilla.org/en-US/kb/automatic-conversion-google-mail-accounts-oauth20" target="_blank">since 91.8.0</a>).</p>
<p>Thunderbird is essentially a Firefox browser which happens to be set up with a GUI that processes emails. So for example, the classic menubar is hidden, but can be revealed by pressing Alt.</p>
<h3>Using the correct profile</h3>
<p>When attempting to run a new version of Thunderbird, be sure to rename ~/.thunderbird into something else, or else the current profile will be upgraded right away. With some luck, the suffixes (e.g. -release) might make Thunderbird ignore the old information, but don&#8217;t trust that.</p>
<p>Actually, it seems like this is handled gracefully anyhow. When I installed exactly the same version on a different position on the disk, it ignored the profile with -release suffix, and added one with -release-1. So go figure.</p>
<p>To select which profile to work with, invoke Thunderbird with Profile Manager with</p>
<pre>$ thunderbird -profilemanager &amp;</pre>
<p>For making the upgrade, first make a backup tarball from the original profile directory.</p>
<p>To adopt in into the new version of Thunderbird, invoke the Profile Manager and pick Create Profile&#8230;, create a new directory (I called it &#8220;mainprofile&#8221;), and pick that as the place for the new profile. Launch Thunderbird, quit right away, and then delete the new directory. Rename the old directory with the new deleted directory&#8217;s name. Then launch Thunderbird again.</p>
<h3>Add-ons</h3>
<p>Previously, I had the following add-ons:</p>
<ul>
<li>BiDi Mail UI (apparently still necessary)</li>
<li>Clippings. Just import the previous clippings from ~/clipdat2.rdf. Unlike the old version, the data is <a rel="noopener" href="https://aecreations.sourceforge.io/clippings/faq.php" target="_blank">kept in a database file</a> inside the profile, so the old file can be deleted.</li>
<li>Gnome Integration Options for calling a command on mail arrival. It was deprecated. So I went for Mailbox Alert, which allows adding specific actions: Sound, a message and/or command. With mail folder granularity, in fact.</li>
<li>Mail Tweak. It&#8217;s really really old, and probably unnecessary since long.</li>
<li>Outgoing Message Format (for text vs. HTML messages). Deprecated since long, as these options are integrated into Thunderbird itself.</li>
</ul>
<p>So I remained with the first two only.</p>
<h3>Installing Thunderbird</h3>
<p>The simplest Thunderbird installation involves downloading it from <a rel="noopener" href="https://www.thunderbird.net/en-US/" target="_blank">their website</a> and extract the tarball somewhere in the user&#8217;s own directories. For a proper installation, I installed it under /usr/local/bin/ with</p>
<pre># tar -C /usr/local/bin -xjvf thunderbird-91.10.0.tar.bz2</pre>
<p>as root. And then reorganize it slightly:</p>
<pre># cd /usr/local/bin
# mv thunderbird thunderbird-91.10.0
# ln -s thunderbird-91.10.0/thunderbird</pre>
<h3>Composing HTML messages</h3>
<p>Right-click the account at the left bar, pick Settings and select the Composition &amp; Addressing item. Make sure Compose messages in HTML is unchecked: Messages should be composed as plain text by default.</p>
<p>Then go through each of the mail identities and verify that Compose messages in HTML is unchecked under the Composition &amp; Addressing tab.</p>
<p>However if Shift is pressed along with clicking Write, Reply or whatever for composing a new message, Thunderbird opens it as HTML.</p>
<h3>Recover old contacts</h3>
<p>Thunderbird went from the old *.mab format to SQLite for keeping the address books. So go Tools &gt; Import&#8230; &gt; Pick Address Books&#8230; and pick Monk Database, and from there pick abook.mab (and posssibly repeat this with history.mab, but I skipped this, because it&#8217;s too much).</p>
<h3>Silencing update notices</h3>
<p>Thunderbird, like most software nowadays, wants to update itself automatically, because who cares if something goes wrong all of the sudden as long as the latest version is installed.</p>
<p>I messed around with this for quite long until I found the solution. So I&#8217;m leaving everything I did written here, but it&#8217;s probably enough with just adding policies.json, as suggested below.</p>
<p>So to the whole story (which you probably want to skip): Under Preferences &gt; General &gt; Updates I selected &#8220;check for updates&#8221; rather than install automatically (it can&#8217;t anyhow, since I&#8217;ve installed Thunderbird as root), but then it starts nagging that there are updates.</p>
<p>So it&#8217;s down to setting the application properties manually by going to Preferences &gt; General &gt; Config Editor&#8230; (button at the bottom).</p>
<p>I changed app.update.promptWaitTime to 31536000 (365 days) but that didn&#8217;t have any effect. So I added an <a href="http://kb.mozillazine.org/App.update.silent" target="_blank">app.update.silent</a> property and set it true, but that didn&#8217;t solve the problem either. So the next step was to change app.update.staging.enabled to false, and that did the trick. Well, almost. With this, Thunderbird didn&#8217;t issue a notification, but its tab on the system tray gets focus every day. Passive aggressive.</p>
<p>As a side note, there are other suggestions I&#8217;ve encountered out there: To change app.update.url so that Thunderbird doesn&#8217;t know where to look for updates, or set app.update.doorhanger false. Haven&#8217;t tried either.</p>
<p>So what actually worked: Create a policies.json in /usr/local/bin/thunderbird/distribution/, with &#8220;<a href="https://github.com/mozilla/policy-templates/blob/master/README.md#disableappupdate" target="_blank">DisableAppUpdate</a>&#8220;: true, that is:</p>
<pre>{
 "policies": {
  "DisableAppUpdate": true
 }
}</pre>
<p>Note that the &#8220;distribution&#8221; directory must be in the same the directory as the actual executable for Thunderbird (that is, follow the symbolic link if such exists). In my case, I had to add this directory myself, because of a manual installation.</p>
<p>And, as suggested on <a href="https://blog.gnu-designs.com/deploying-firefox-and-thunderbird-policies-to-prevent-auto-updates-and-tune-other-features/" target="_blank">this page</a>, the successful deployment can be verified by restarting Thunderbird, and then looking at Help &gt; About inside Thunderbird, which now says (note the comment on updates being disabled):</p>
<p style="text-align: left;"><img class="aligncenter size-medium wp-image-6653" title="The About window after disabling updates with policies.json" src="https://billauer.se/blog/wp-content/uploads/2022/06/disable-updates.png" alt="The About window after disabling updatess with policies.json" width="653" height="337" />In hindsight, I can speculate on why this works: The authors of Thunderbird really don&#8217;t want us to turn off automatic updates, mainly because if people start running outdated software, that increases the chance of a widespread attack on some vulnerability, which can damage the software&#8217;s reputation. So Thunderbird is designed to ignore previous possibilities to turn the update off.</p>
<p style="text-align: left;">There&#8217;s only one case where there&#8217;s no choice: If Thunderbird was installed by the distribution. In this case, it&#8217;s installed as root, so it can&#8217;t be updated by a plain user. Hence it&#8217;s the distribution&#8217;s role to nag. And it has the same interest to nag about upgrades (reputation and that).</p>
<p style="text-align: left;">So I guess that&#8217;s why Thunderbird respects this JSON file only.</p>
<h3>Folders with new mails in red</h3>
<p><a rel="noopener" href="https://billauer.se/blog/2012/05/thunderbird-tweaks/" target="_blank">Exactly like 10 years ago</a>, the trick is to create a &#8220;chrome&#8221; directory under .thunderbird/ and then add the following file:</p>
<pre>$ cat ~/.thunderbird/sdf2k45i.default/chrome/userChrome.css
@namespace
url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */

/* Setting the color of folders containing new messages to red */

treechildren::-moz-tree-cell-text(folderNameCol, newMessages-true) {
 font-weight: bold;
 color: red !important;
}</pre>
<p>But unlike old Thunderbird, this file isn&#8217;t read by default. So to fix that, go to Preferences &gt; General &gt; Config Editor&#8230; (button at the bottom) and there change toolkit.legacyUserProfileCustomizations.stylesheets to true.</p>
<h3>New mail icon in system tray</h3>
<p>Thunderbird sends a regular notification when a new mail arrives, but exactly like <a rel="noopener" href="https://billauer.se/blog/2012/05/linux-icon-system-tray-thunderbird-zenity/" target="_blank">last time</a>, I want a dedicated icon that is dismissed only when I click it. The rationale is to be able to see if a new mail has arrived at a quick glance of the system tray. Neither zenity &#8211;notification nor send-notify were good for this, since they send the common notification (zenity used to just add an icon, but it &#8220;got better&#8221;).</p>
<p>But then there&#8217;s yad. I began with &#8220;apt install yad&#8221;, but that gave me a really old version that distorted the icon in the system bar. So I installed it from the <a rel="noopener" href="https://github.com/v1cont/yad" target="_blank">git repository&#8217;s</a> tag 1.0. I first attempted v12.0, but I ended up with the problem <a rel="noopener" href="https://githubmemory.com/repo/v1cont/yad/issues/119" target="_blank">mentioned here</a>, and didn&#8217;t want to mess around with it more.</p>
<p>Its &#8220;make install&#8221; adds /usr/local/bin/yad, as well as a lot of yad.mo under /usr/local/share/locale/*, a lot of yad.png under /usr/local/share/icons/*, yad.m4 under /usr/local/share/aclocal/ and yad.1 + pfd.1 in /usr/local/share/man/man1. So quite a lot of files, but in a sensible way.</p>
<p>With this done, the following script is kept (as executable) as /usr/local/bin/new-mail-icon:</p>
<pre><span class="hljs-comment">#!/usr/bin/perl</span>
<span class="hljs-keyword">use</span> warnings;
<span class="hljs-keyword">use</span> strict;
<span class="hljs-keyword">use</span> Fcntl <span class="hljs-string">qw[ :flock ]</span>;

<span class="hljs-keyword">my</span> $THEDIR=<span class="hljs-string">"$ENV{HOME}/.thunderbird"</span>;
<span class="hljs-keyword">my</span> $ICON=<span class="hljs-string">"$THEDIR/green-mail-unread.png"</span>;

<span class="hljs-keyword">my</span> $NOW=<span class="hljs-keyword">scalar</span> <span class="hljs-keyword">localtime</span>;

<span class="hljs-keyword">open</span>(<span class="hljs-keyword">my</span> $fh, <span class="hljs-string">"&lt;"</span>, <span class="hljs-string">"$ICON"</span>)
  <span class="hljs-keyword">or</span> <span class="hljs-keyword">die</span> <span class="hljs-string">"Can't open $ICON for read: $!"</span>;

<span class="hljs-comment"># Lock the file. If it's already locked, the icon is already</span>
<span class="hljs-comment"># in the tray, so fail silently (and don't block).</span>

<span class="hljs-keyword">flock</span>($fh, LOCK_EX | LOCK_NB) <span class="hljs-keyword">or</span> <span class="hljs-keyword">exit</span> <span class="hljs-number">0</span>;

<span class="hljs-keyword">fork</span>() &amp;&amp; <span class="hljs-keyword">exit</span> <span class="hljs-number">0</span>; <span class="hljs-comment"># Only child continues</span>

<span class="hljs-keyword">system</span>(<span class="hljs-string">'yad'</span>, <span class="hljs-string">'--notification'</span>, <span class="hljs-string">"--text=New mail on $NOW"</span>, <span class="hljs-string">"--image=$ICON"</span>, <span class="hljs-string">'--icon-size=32'</span>);</pre>
<p>This script is the improved version of the <a rel="noopener" href="https://billauer.se/blog/2012/05/linux-icon-system-tray-thunderbird-zenity/" target="_blank">previous one</a>, and it prevents multiple icons in the tray much better: It locks the icon file exclusively and without blocking. Hence if there&#8217;s any other process that shows the icon, subsequent attempts to lock this file fail immediately.</p>
<p>Since the &#8220;yad&#8221; call takes a second or two, the scripts forks and exits before that, so it doesn&#8217;t delay Thunderbird&#8217;s machinery.</p>
<p>With this script in place, the Mailbox Alert is configured as follows. Add a new item to the list as in this dialog box:</p>
<p><a href="https://billauer.se/blog/wp-content/uploads/2022/06/new-mail-dialogbox.png"><img class="aligncenter size-full wp-image-6620" title="Setting dialog box for Mailbox Alert extension" src="https://billauer.se/blog/wp-content/uploads/2022/06/new-mail-dialogbox.png" alt="Setting dialog box for Mailbox Alert extension" width="566" height="407" /></a></p>
<p>The sound should be set to a WAV file of choice.</p>
<p>Then right-click the mail folder to have covered (Local Folders in my case), pick Mailbox Alert and enable &#8220;New Mail&#8221; and &#8220;Alert for child folders&#8221;.</p>
<p>Then right-click &#8220;Inbox&#8221; under this folder, and verify that nothing is checked for Mailbox Alert for it (in particular not &#8220;Default sound&#8221;). That except for the Outbox and Draft folders, for which &#8220;Don&#8217;t let parent folders alert for this one&#8221; should be checked, or else there&#8217;s a false alarm on autosaving and when using &#8220;send later&#8221;.</p>
<p>Later on, I changed my mind and added a message popup, so now all three checkboxes are ticked, and the Message tab reads:</p>
<p><a href="https://billauer.se/blog/wp-content/uploads/2022/06/mail-alert-with-message.png"><img class="aligncenter size-full wp-image-6624" title="Mail Alert dialog box, after update" src="https://billauer.se/blog/wp-content/uploads/2022/06/mail-alert-with-message.png" alt="Mail Alert dialog box, after update" width="566" height="407" /></a></p>
<p>I picked the icon as /usr/local/bin/thunderbird-91.10.0/chrome/icons/default/default32.png (this depends on the installation path, of course).</p>
<p>I&#8217;m not 100% clear why the original alert didn&#8217;t show up, even though &#8220;Show an alert&#8221; was still checked under &#8220;Incoming Mails&#8221; at Preferences &gt; General. I actually preferred the good old one, but it seems like Mailbox Alert muted it. I unchecked it anyhow, just to be safe.</p>
<h3>Refusing to remember passwords + failing to sent through gmail</h3>
<p>It&#8217;s not a real upgrade if a weird problem doesn&#8217;t occur out of the blue.</p>
<p>So attempting to Get Messages from pop3 server at localhost failed quite oddly: Every time I checked the box to use Password Manager to remember the password, it got stuck with &#8220;Main: Connected to 127.0.0.1&#8230;&#8221;. But checking with Wireshark, it turned out that Thunderbird asked the server about its capabilities (CAPA), got an answer and then did nothing for about 10 seconds, after which it closed the connection.</p>
<p>On the other hand, when I didn&#8217;t request remembering the password, it went fine, and so did subsequent attempts to fetch mail from the pop3 server.</p>
<p>Another thing was that when attempting to use Gmail&#8217;s server, I went through the entire OAuth2 thing (the browser window, and asking for my permissions) but then the mail was just stuck on &#8220;Sending message&#8221;. Like, forever.</p>
<p>So I followed the advice <a rel="noopener" href="https://support.mozilla.org/en-US/questions/1342635" target="_blank">here</a>, and deleted key3.db, key4.db, secmod.db, cert*.db and all signon* files with Thunderbird not running of course. Really old stuff.</p>
<p>And that fixed it.</p>
<p>The files that were apparently created when things got fine were logins.json, cert9.db, key4.db and pkcs11.txt. But I might have missed something.</p>
<h3>The GUI stuck for a few seconds every now and then</h3>
<p>This happened occasionally when I navigated from one mail folder to another. The solution I found somewhere was to delete all .msf files from where Thunderbird keeps the mail info, and that did the trick. Ehm, just for a while. After a few days, it was back.</p>
<p>As a side effect, it forgot the display settings for each folder, i.e. which columns to show and in what order.</p>
<p>These .msf files are apparently indexes to the files containing the actual messages, and indeed it took a few seconds before something appeared when I went to view each mail folder for the first time. At which time the new .msf files went from zero bytes to a significant figure.</p>
<p>Since the problem remains, I watched &#8220;top&#8221; when the GUI got stuck. And indeed, Thunderbird&#8217;s process was at 100%, but so was a completely different process: caribou. Which is a virtual keyboard. Do I need one? No. So to get rid of this process (which runs all the time, but doesn&#8217;t eat a lot of CPU normally), go Accessibility settings, the Keyboard tab and turn &#8220;Enable the on-screen keyboard&#8221; off. The process is gone, and so is the problem with the GUI? Nope. It&#8217;s basically the same, but instead of two processes taking 100% CPU, now it&#8217;s Thunderbird alone. I have no idea what to do next.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2022/06/thunderbird-installation-oauth2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox: Stop that nagging on available updates</title>
		<link>https://billauer.se/blog/2020/01/firefox-disable-automatic-update-checks/</link>
		<comments>https://billauer.se/blog/2020/01/firefox-disable-automatic-update-checks/#comments</comments>
		<pubDate>Wed, 29 Jan 2020 05:35:18 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[stop updates]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=5964</guid>
		<description><![CDATA[After upgrading to Firefox 72.0.1 on Linux, I got a tab encouraging me to upgrade Firefox (and that it couldn&#8217;t be done automatically). To make things worse, the option to turn off automatic upgrades checks has been removed from the GUI interface. Why? Call it what you want, at the bottom there&#8217;s a &#8220;let&#8217;s force [...]]]></description>
			<content:encoded><![CDATA[<p>After upgrading to Firefox 72.0.1 on Linux, I got a tab encouraging me to upgrade Firefox (and that it couldn&#8217;t be done automatically). To make things worse, the option to turn off automatic upgrades checks has been removed from the GUI interface. Why? Call it what you want, at the bottom there&#8217;s a &#8220;let&#8217;s force people to do it&#8221; attitude behind it. Seen it so many times before, and also seen disasters resulting from it.</p>
<p>Upgrading is important for security, yes, but thanks, I don&#8217;t need to be reminded every time a microversion upgrade is available. Some people enjoy spending quality time with their computer, updating all software and then fixing things that broke because of that. I&#8217;m not one of them.</p>
<p>The solution for now (taken from <a href="https://www.reddit.com/r/firefox/comments/bxuvsn/how_to_completely_block_update_checks/" target="_blank">here</a>) is to add the following file as /usr/lib/firefox/distribution/policies.json :</p>
<pre>{
 "policies": {
 "AppUpdateURL": "http://127.0.0.1/",
 "DisableAppUpdate": true,
 "DisableFirefoxStudies": true,
 "DisableSystemAddonUpdate": true,
 "DisableTelemetry": true,
 "ExtensionUpdate": false
 }
}</pre>
<p>The location may vary of course, and the &#8220;distribution&#8221; directory may need to be created. In my system, Firefox is run from /usr/bin/firefox which is a symlink to /usr/lib/firefox/firefox (so /usr/lib/firefox is the installation directory for this purpose).</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2020/01/firefox-disable-automatic-update-checks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
