Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ab081e3 authored by Jason Monk's avatar Jason Monk
Browse files

Potential fix for receiver leak problem

The background thread is not stopping listening fast enough and is
resulting in first a receiver leak message followed by a crash when
trying to finally unregister the receiver.

Fix this by adding a registerReceiver to SummaryLoader that will
automatically unregister the receiver on the main thread to ensure
it happens in time.

Change-Id: I0104e929d5505eb53993f6765e4c90120df35cf6
Fixes: 28211606
parent 39975a60
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -16,8 +16,14 @@
package com.android.settings.dashboard;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.os.*;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.ArrayMap;
import android.util.Log;
@@ -45,6 +51,7 @@ public class SummaryLoader {

    private DashboardAdapter mAdapter;
    private boolean mListening;
    private ArrayList<BroadcastReceiver> mReceivers = new ArrayList<>();

    public SummaryLoader(Activity activity, List<DashboardCategory> categories) {
        mHandler = new Handler();
@@ -88,6 +95,14 @@ public class SummaryLoader {
    }

    public void setListening(boolean listening) {
        synchronized (mReceivers) {
            // Unregister listeners immediately.
            mListening = false;
            for (int i = 0; i < mReceivers.size(); i++) {
                mActivity.unregisterReceiver(mReceivers.get(i));
            }
            mReceivers.clear();
        }
        mWorker.obtainMessage(Worker.MSG_SET_LISTENING, listening ? 1 : 0, 0).sendToTarget();
    }

@@ -128,13 +143,28 @@ public class SummaryLoader {
        return tile.metaData;
    }

    /**
     * Registers a receiver and automatically unregisters it when the activity is stopping.
     * This ensures that the receivers are unregistered immediately, since most summary loader
     * operations are asynchronous.
     */
    public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        synchronized (mReceivers) {
            if (!mListening) {
                return;
            }
            mReceivers.add(receiver);
            mActivity.registerReceiver(receiver, filter);
        }
    }

    private synchronized void setListeningW(boolean listening) {
        if (mListening == listening) return;
        if (DEBUG) Log.d(TAG, "Listening " + listening);
        mListening = listening;
        for (SummaryProvider p : mSummaryMap.keySet()) {
            p.setListening(listening);
        }
        mListening = listening;
    }

    private synchronized void makeProviderW(Tile tile) {
+1 −8
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
@@ -39,15 +38,12 @@ import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.Spannable;
import android.text.style.TextAppearanceSpan;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
@@ -58,7 +54,6 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.BufferType;
import android.widget.Toast;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.LinkifyUtils;
@@ -999,9 +994,7 @@ public class WifiSettings extends RestrictedSettingsFragment
                filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
                filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
                filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
                mContext.registerReceiver(this, filter);
            } else {
                mContext.unregisterReceiver(this);
                mSummaryLoader.registerReceiver(this, filter);
            }
        }