Home | History | Annotate | Download | only in timezone
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.timezone;
     18 
     19 import com.android.server.EventLogTags;
     20 
     21 import android.app.timezone.RulesUpdaterContract;
     22 import android.content.BroadcastReceiver;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.IntentFilter;
     26 import android.os.PatternMatcher;
     27 import android.os.UserHandle;
     28 import android.util.Slog;
     29 
     30 /**
     31  * The bona fide implementation of {@link PackageTrackerIntentHelper}.
     32  */
     33 final class PackageTrackerIntentHelperImpl implements PackageTrackerIntentHelper {
     34 
     35     private final static String TAG = "timezone.PackageTrackerIntentHelperImpl";
     36 
     37     private final Context mContext;
     38     private String mUpdaterAppPackageName;
     39 
     40     PackageTrackerIntentHelperImpl(Context context) {
     41         mContext = context;
     42     }
     43 
     44     @Override
     45     public void initialize(String updaterAppPackageName, String dataAppPackageName,
     46             PackageTracker packageTracker) {
     47         mUpdaterAppPackageName = updaterAppPackageName;
     48 
     49         // Register for events of interest.
     50 
     51         // The intent filter that triggers when package update events happen that indicate there may
     52         // be work to do.
     53         IntentFilter packageIntentFilter = new IntentFilter();
     54 
     55         packageIntentFilter.addDataScheme("package");
     56         packageIntentFilter.addDataSchemeSpecificPart(
     57                 updaterAppPackageName, PatternMatcher.PATTERN_LITERAL);
     58         packageIntentFilter.addDataSchemeSpecificPart(
     59                 dataAppPackageName, PatternMatcher.PATTERN_LITERAL);
     60 
     61         // ACTION_PACKAGE_ADDED is fired when a package is upgraded or downgraded (in addition to
     62         // ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED). A system/priv-app can never be
     63         // removed entirely so we do not need to trigger on ACTION_PACKAGE_REMOVED or
     64         // ACTION_PACKAGE_FULLY_REMOVED.
     65         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
     66 
     67         // ACTION_PACKAGE_CHANGED is used when a package is disabled / re-enabled. It is not
     68         // strictly necessary to trigger on this but it won't hurt anything and may catch some cases
     69         // where a package has changed while disabled.
     70         // Note: ACTION_PACKAGE_CHANGED is not fired when updating a suspended app, but
     71         // ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED are (and the app
     72         // is left in an unsuspended state after this).
     73         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
     74 
     75         // We do not register for ACTION_PACKAGE_RESTARTED because it doesn't imply an update.
     76         // We do not register for ACTION_PACKAGE_DATA_CLEARED because the updater / data apps are
     77         // not expected to need local data.
     78 
     79         Receiver packageUpdateReceiver = new Receiver(packageTracker);
     80         mContext.registerReceiverAsUser(
     81                 packageUpdateReceiver, UserHandle.SYSTEM, packageIntentFilter,
     82                 null /* broadcastPermission */, null /* default handler */);
     83     }
     84 
     85     /** Sends an intent to trigger an update check. */
     86     @Override
     87     public void sendTriggerUpdateCheck(CheckToken checkToken) {
     88         RulesUpdaterContract.sendBroadcast(
     89                 mContext, mUpdaterAppPackageName, checkToken.toByteArray());
     90         EventLogTags.writeTimezoneTriggerCheck(checkToken.toString());
     91     }
     92 
     93     @Override
     94     public synchronized void scheduleReliabilityTrigger(long minimumDelayMillis) {
     95         TimeZoneUpdateIdler.schedule(mContext, minimumDelayMillis);
     96     }
     97 
     98     @Override
     99     public synchronized void unscheduleReliabilityTrigger() {
    100         TimeZoneUpdateIdler.unschedule(mContext);
    101     }
    102 
    103     private static class Receiver extends BroadcastReceiver {
    104         private final PackageTracker mPackageTracker;
    105 
    106         private Receiver(PackageTracker packageTracker) {
    107             mPackageTracker = packageTracker;
    108         }
    109 
    110         @Override
    111         public void onReceive(Context context, Intent intent) {
    112             Slog.d(TAG, "Received intent: " + intent.toString());
    113             mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
    114         }
    115     }
    116 }
    117