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.util.Slog;
     28 
     29 /**
     30  * The bona fide implementation of {@link IntentHelper}.
     31  */
     32 final class IntentHelperImpl implements IntentHelper {
     33 
     34     private final static String TAG = "timezone.IntentHelperImpl";
     35 
     36     private final Context mContext;
     37     private String mUpdaterAppPackageName;
     38 
     39     IntentHelperImpl(Context context) {
     40         mContext = context;
     41     }
     42 
     43     @Override
     44     public void initialize(String updaterAppPackageName, String dataAppPackageName,
     45             PackageTracker packageTracker) {
     46         mUpdaterAppPackageName = updaterAppPackageName;
     47 
     48         // Register for events of interest.
     49 
     50         // The intent filter that triggers when package update events happen that indicate there may
     51         // be work to do.
     52         IntentFilter packageIntentFilter = new IntentFilter();
     53 
     54         packageIntentFilter.addDataScheme("package");
     55         packageIntentFilter.addDataSchemeSpecificPart(
     56                 updaterAppPackageName, PatternMatcher.PATTERN_LITERAL);
     57         packageIntentFilter.addDataSchemeSpecificPart(
     58                 dataAppPackageName, PatternMatcher.PATTERN_LITERAL);
     59 
     60         // ACTION_PACKAGE_ADDED is fired when a package is upgraded or downgraded (in addition to
     61         // ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED). A system/priv-app can never be
     62         // removed entirely so we do not need to trigger on ACTION_PACKAGE_REMOVED or
     63         // ACTION_PACKAGE_FULLY_REMOVED.
     64         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
     65 
     66         // ACTION_PACKAGE_CHANGED is used when a package is disabled / re-enabled. It is not
     67         // strictly necessary to trigger on this but it won't hurt anything and may catch some cases
     68         // where a package has changed while disabled.
     69         // Note: ACTION_PACKAGE_CHANGED is not fired when updating a suspended app, but
     70         // ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and ACTION_PACKAGE_REPLACED are (and the app
     71         // is left in an unsuspended state after this).
     72         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
     73 
     74         // We do not register for ACTION_PACKAGE_RESTARTED because it doesn't imply an update.
     75         // We do not register for ACTION_PACKAGE_DATA_CLEARED because the updater / data apps are
     76         // not expected to need local data.
     77 
     78         Receiver packageUpdateReceiver = new Receiver(packageTracker);
     79         mContext.registerReceiver(packageUpdateReceiver, packageIntentFilter);
     80     }
     81 
     82     /** Sends an intent to trigger an update check. */
     83     @Override
     84     public void sendTriggerUpdateCheck(CheckToken checkToken) {
     85         RulesUpdaterContract.sendBroadcast(
     86                 mContext, mUpdaterAppPackageName, checkToken.toByteArray());
     87         EventLogTags.writeTimezoneTriggerCheck(checkToken.toString());
     88     }
     89 
     90     @Override
     91     public synchronized void scheduleReliabilityTrigger(long minimumDelayMillis) {
     92         TimeZoneUpdateIdler.schedule(mContext, minimumDelayMillis);
     93     }
     94 
     95     @Override
     96     public synchronized void unscheduleReliabilityTrigger() {
     97         TimeZoneUpdateIdler.unschedule(mContext);
     98     }
     99 
    100     private static class Receiver extends BroadcastReceiver {
    101         private final PackageTracker mPackageTracker;
    102 
    103         private Receiver(PackageTracker packageTracker) {
    104             mPackageTracker = packageTracker;
    105         }
    106 
    107         @Override
    108         public void onReceive(Context context, Intent intent) {
    109             Slog.d(TAG, "Received intent: " + intent.toString());
    110             mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
    111         }
    112     }
    113 }
    114