168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller/*
268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * Copyright (C) 2017 The Android Open Source Project
368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller *
468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * you may not use this file except in compliance with the License.
668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * You may obtain a copy of the License at
768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller *
868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller *
1068f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * Unless required by applicable law or agreed to in writing, software
1168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
1268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * See the License for the specific language governing permissions and
1468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller * limitations under the License.
1568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller */
1668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
1768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerpackage com.android.server.timezone;
1868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
19d857f676744af55c79c4871c881bf9598f6b21e9Neil Fullerimport com.android.server.EventLogTags;
20d857f676744af55c79c4871c881bf9598f6b21e9Neil Fuller
2168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.app.timezone.RulesUpdaterContract;
2268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.content.BroadcastReceiver;
2368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.content.Context;
2468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.content.Intent;
2568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.content.IntentFilter;
2668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.os.PatternMatcher;
271281f39f86a8e4d9950581fb1f15245843856c23Neil Fullerimport android.os.UserHandle;
2868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fullerimport android.util.Slog;
2968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
3068f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller/**
31b144227742ada7fd693684a5bd2d53abd8e7c499Neil Fuller * The bona fide implementation of {@link PackageTrackerIntentHelper}.
3268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller */
33b144227742ada7fd693684a5bd2d53abd8e7c499Neil Fullerfinal class PackageTrackerIntentHelperImpl implements PackageTrackerIntentHelper {
3468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
35b144227742ada7fd693684a5bd2d53abd8e7c499Neil Fuller    private final static String TAG = "timezone.PackageTrackerIntentHelperImpl";
3668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
3768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    private final Context mContext;
3868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    private String mUpdaterAppPackageName;
3968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
40b144227742ada7fd693684a5bd2d53abd8e7c499Neil Fuller    PackageTrackerIntentHelperImpl(Context context) {
4168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        mContext = context;
4268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    }
4368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
4468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    @Override
45cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller    public void initialize(String updaterAppPackageName, String dataAppPackageName,
46cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller            PackageTracker packageTracker) {
4768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        mUpdaterAppPackageName = updaterAppPackageName;
4868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
4968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        // Register for events of interest.
5068f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
5168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        // The intent filter that triggers when package update events happen that indicate there may
5268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        // be work to do.
5368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        IntentFilter packageIntentFilter = new IntentFilter();
54228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller
5568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        packageIntentFilter.addDataScheme("package");
5668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        packageIntentFilter.addDataSchemeSpecificPart(
5768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller                updaterAppPackageName, PatternMatcher.PATTERN_LITERAL);
5868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        packageIntentFilter.addDataSchemeSpecificPart(
5968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller                dataAppPackageName, PatternMatcher.PATTERN_LITERAL);
60228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller
61228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // ACTION_PACKAGE_ADDED is fired when a package is upgraded or downgraded (in addition to
62228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED). A system/priv-app can never be
63228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // removed entirely so we do not need to trigger on ACTION_PACKAGE_REMOVED or
64228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // ACTION_PACKAGE_FULLY_REMOVED.
65228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
66228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller
67228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // ACTION_PACKAGE_CHANGED is used when a package is disabled / re-enabled. It is not
68228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // strictly necessary to trigger on this but it won't hurt anything and may catch some cases
69228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // where a package has changed while disabled.
70228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // Note: ACTION_PACKAGE_CHANGED is not fired when updating a suspended app, but
71228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED are (and the app
72228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // is left in an unsuspended state after this).
73228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
74228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller
75228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // We do not register for ACTION_PACKAGE_RESTARTED because it doesn't imply an update.
76228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // We do not register for ACTION_PACKAGE_DATA_CLEARED because the updater / data apps are
77228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller        // not expected to need local data.
78228dc6cfefd06936657fa39848f7ee73162def8fNeil Fuller
79cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller        Receiver packageUpdateReceiver = new Receiver(packageTracker);
801281f39f86a8e4d9950581fb1f15245843856c23Neil Fuller        mContext.registerReceiverAsUser(
811281f39f86a8e4d9950581fb1f15245843856c23Neil Fuller                packageUpdateReceiver, UserHandle.SYSTEM, packageIntentFilter,
821281f39f86a8e4d9950581fb1f15245843856c23Neil Fuller                null /* broadcastPermission */, null /* default handler */);
8368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    }
8468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
8568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    /** Sends an intent to trigger an update check. */
8668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    @Override
8768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    public void sendTriggerUpdateCheck(CheckToken checkToken) {
8868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        RulesUpdaterContract.sendBroadcast(
8968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller                mContext, mUpdaterAppPackageName, checkToken.toByteArray());
90d857f676744af55c79c4871c881bf9598f6b21e9Neil Fuller        EventLogTags.writeTimezoneTriggerCheck(checkToken.toString());
9168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    }
9268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
9368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    @Override
94cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller    public synchronized void scheduleReliabilityTrigger(long minimumDelayMillis) {
95cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller        TimeZoneUpdateIdler.schedule(mContext, minimumDelayMillis);
9668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    }
9768f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
9868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    @Override
99cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller    public synchronized void unscheduleReliabilityTrigger() {
100cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller        TimeZoneUpdateIdler.unschedule(mContext);
10168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    }
10268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
10368f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    private static class Receiver extends BroadcastReceiver {
104cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller        private final PackageTracker mPackageTracker;
10568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
106cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller        private Receiver(PackageTracker packageTracker) {
107cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller            mPackageTracker = packageTracker;
10868f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        }
10968f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller
11068f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        @Override
11168f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        public void onReceive(Context context, Intent intent) {
11268f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller            Slog.d(TAG, "Received intent: " + intent.toString());
113cd1a109b872f58f5baa0ce8438bf3ddd69eec9fcNeil Fuller            mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
11468f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller        }
11568f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller    }
11668f666693a465eb8a66d9252b7b7ac035b9f0b7bNeil Fuller}
117