PackageIntentsReceiver.java revision 1d0b46b08f220dee0426b2b934405ec581e1c817
1/*
2 * Copyright (C) 2014 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
17package com.android.tv.receiver;
18
19import android.content.BroadcastReceiver;
20import android.content.ComponentName;
21import android.content.Context;
22import android.content.Intent;
23import android.content.SharedPreferences;
24import android.content.pm.PackageManager;
25import android.net.Uri;
26import android.os.Handler;
27import android.tv.TvInputInfo;
28import android.tv.TvInputManager;
29
30import com.android.tv.TvActivity;
31import com.android.tv.util.TvSettings;
32import com.android.tv.util.Utils;
33
34import java.util.HashSet;
35import java.util.List;
36import java.util.Set;
37
38/**
39 * A class for handling the broadcast intents from PackageManager.
40 */
41public class PackageIntentsReceiver extends BroadcastReceiver {
42
43    // Delay before checking TvInputManager's input list.
44    // Sometimes TvInputManager's input list isn't updated yet when this receiver is called.
45    // So we should check the list after some delay.
46    private static final long TV_INPUT_UPDATE_DELAY_MS = 500;
47
48    private TvInputManager mTvInputManager;
49    private SharedPreferences mPreferences;
50    private Handler mHandler = new Handler();
51    private Runnable mTvActivityUpdater;
52    private Runnable mDisplayInputNameCleaner;
53
54    private void init(Context context) {
55        mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
56        mPreferences = Utils.getSharedPreferencesOfDisplayNameForInput(context);
57
58        final Context applicationContext = context.getApplicationContext();
59        mTvActivityUpdater = new Runnable() {
60            @Override
61            public void run() {
62                enableTvActivityWithinPackageManager(applicationContext,
63                        !mTvInputManager.getTvInputList().isEmpty());
64            }
65        };
66
67        mDisplayInputNameCleaner = new Runnable() {
68            @Override
69            public void run() {
70                cleanupUnusedDisplayInputName();
71            }
72        };
73    }
74
75    @Override
76    public void onReceive(Context context, Intent intent) {
77        if (mTvInputManager == null) {
78            init(context);
79        }
80
81        String action = intent.getAction();
82        if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
83            Uri uri = intent.getData();
84            onPackageFullyRemoved(uri != null ? uri.getSchemeSpecificPart() : null);
85        }
86
87        mHandler.removeCallbacks(mTvActivityUpdater);
88        mHandler.postDelayed(mTvActivityUpdater, TV_INPUT_UPDATE_DELAY_MS);
89    }
90
91    private void onPackageFullyRemoved(String packageName) {
92        if (packageName == null || packageName.isEmpty()) {
93            return;
94        }
95
96        mHandler.removeCallbacks(mDisplayInputNameCleaner);
97        mHandler.postDelayed(mDisplayInputNameCleaner, TV_INPUT_UPDATE_DELAY_MS);
98    }
99
100    private void cleanupUnusedDisplayInputName() {
101        Set<String> keys = mPreferences.getAll().keySet();
102        HashSet<String> unusedKeys = new HashSet<String>(keys);
103        for (String key : keys) {
104            if (!key.startsWith(TvSettings.PREF_DISPLAY_INPUT_NAME)) {
105                unusedKeys.remove(key);
106            }
107        }
108        List<TvInputInfo> inputs = mTvInputManager.getTvInputList();
109        for (TvInputInfo input : inputs) {
110            unusedKeys.remove(TvSettings.PREF_DISPLAY_INPUT_NAME + input.getId());
111        }
112        if (!unusedKeys.isEmpty()) {
113            SharedPreferences.Editor editor = mPreferences.edit();
114            for (String key : unusedKeys) {
115                editor.remove(key);
116            }
117            editor.commit();
118        }
119    }
120
121    private void enableTvActivityWithinPackageManager(Context context, boolean enable) {
122        PackageManager pm = context.getPackageManager();
123        ComponentName name = new ComponentName(context, TvActivity.class);
124
125        int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
126                PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
127        if (pm.getComponentEnabledSetting(name) != newState) {
128            pm.setComponentEnabledSetting(name, newState, PackageManager.DONT_KILL_APP);
129        }
130    }
131}
132