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

Commit e5a6f821 authored by Adam Powell's avatar Adam Powell Committed by Android (Google) Code Review
Browse files

Merge "Don't register more receivers and observers for every DateTimeView" into lmp-mr1-dev

parents aed8e761 740da475
Loading
Loading
Loading
Loading
+85 −41
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.widget.RemoteViews.RemoteView;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

//
@@ -62,8 +63,8 @@ public class DateTimeView extends TextView {
    int mLastDisplay = -1;
    DateFormat mLastFormat;

    private boolean mAttachedToWindow;
    private long mUpdateTimeMillis;
    private static final ThreadLocal<ReceiverInfo> sReceiverInfo = new ThreadLocal<ReceiverInfo>();

    public DateTimeView(Context context) {
        super(context);
@@ -76,15 +77,21 @@ public class DateTimeView extends TextView {
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        registerReceivers();
        mAttachedToWindow = true;
        ReceiverInfo ri = sReceiverInfo.get();
        if (ri == null) {
            ri = new ReceiverInfo();
            sReceiverInfo.set(ri);
        }
        ri.addView(this);
    }
        
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        unregisterReceivers();
        mAttachedToWindow = false;
        final ReceiverInfo ri = sReceiverInfo.get();
        if (ri != null) {
            ri.removeView(this);
        }
    }

    @android.view.RemotableViewMethod
@@ -204,32 +211,19 @@ public class DateTimeView extends TextView {
        }
    }

    private void registerReceivers() {
        Context context = getContext();

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_TICK);
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        context.registerReceiver(mBroadcastReceiver, filter);

        Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT);
        context.getContentResolver().registerContentObserver(uri, true, mContentObserver);
    }

    private void unregisterReceivers() {
        Context context = getContext();
        context.unregisterReceiver(mBroadcastReceiver);
        context.getContentResolver().unregisterContentObserver(mContentObserver);
    void clearFormatAndUpdate() {
        mLastFormat = null;
        update();
    }

    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    private static class ReceiverInfo {
        private final ArrayList<DateTimeView> mAttachedViews = new ArrayList<DateTimeView>();
        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (Intent.ACTION_TIME_TICK.equals(action)) {
                if (System.currentTimeMillis() < mUpdateTimeMillis) {
                    if (System.currentTimeMillis() < getSoonestUpdateTime()) {
                        // The update() function takes a few milliseconds to run because of
                        // all of the time conversions it needs to do, so we can't do that
                        // every minute.
@@ -237,16 +231,66 @@ public class DateTimeView extends TextView {
                    }
                }
                // ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format.
            mLastFormat = null;
            update();
                updateAll();
            }
        };

    private ContentObserver mContentObserver = new ContentObserver(new Handler()) {
        private final ContentObserver mObserver = new ContentObserver(new Handler()) {
            @Override
            public void onChange(boolean selfChange) {
            mLastFormat = null;
            update();
                updateAll();
            }
        };

        public void addView(DateTimeView v) {
            final boolean register = mAttachedViews.isEmpty();
            mAttachedViews.add(v);
            if (register) {
                register(v.getContext().getApplicationContext());
            }
        }

        public void removeView(DateTimeView v) {
            mAttachedViews.remove(v);
            if (mAttachedViews.isEmpty()) {
                unregister(v.getContext().getApplicationContext());
            }
        }

        void updateAll() {
            final int count = mAttachedViews.size();
            for (int i = 0; i < count; i++) {
                mAttachedViews.get(i).clearFormatAndUpdate();
            }
        }

        long getSoonestUpdateTime() {
            long result = Long.MAX_VALUE;
            final int count = mAttachedViews.size();
            for (int i = 0; i < count; i++) {
                final long time = mAttachedViews.get(i).mUpdateTimeMillis;
                if (time < result) {
                    result = time;
                }
            }
            return result;
        }

        void register(Context context) {
            final IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_TIME_TICK);
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            context.registerReceiver(mReceiver, filter);

            final Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT);
            context.getContentResolver().registerContentObserver(uri, true, mObserver);
        }

        void unregister(Context context) {
            context.unregisterReceiver(mReceiver);
            context.getContentResolver().unregisterContentObserver(mObserver);
        }
    }
}