1 /*
2  * Copyright (C) 2016 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.example.sampleleanbacklauncher;
18 
19 import android.annotation.TargetApi;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.SharedPreferences;
24 import android.content.pm.ApplicationInfo;
25 import android.content.pm.PackageManager;
26 import android.content.pm.ResolveInfo;
27 import android.preference.PreferenceManager;
28 import android.provider.Settings;
29 
30 import java.util.List;
31 
32 /**
33  * This is an optional component whose job is to ensure that the system is up-to-date
34  * at boot time.  It delegates this operation to a separate application on the device.
35  */
36 @TargetApi(24)
37 public class SystemUpdateChecker {
38 
39     /**
40      * The application that handles the system update check must be a system application that
41      * has an activity found by this action.
42      */
43     private static final String ACTION_TV_BOOT_COMPLETED =
44             "android.intent.action.TV_BOOT_COMPLETED";
45 
46     private static final String PREF_SYSTEM_CHECKED_BOOT_COUNT = "system.checked.boot.count";
47 
48     private final Context mContext;
49 
SystemUpdateChecker(Context context)50     public SystemUpdateChecker(Context context) {
51         mContext = context;
52     }
53 
getSystemUpdateCheckerIntent()54     Intent getSystemUpdateCheckerIntent() {
55         // See if we have already performed a system update check since the latest boot
56         // of the device
57         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
58         int checkedBootCount = prefs.getInt(PREF_SYSTEM_CHECKED_BOOT_COUNT, -1);
59         if (checkedBootCount >= getBootCount()) {
60             return null;
61         }
62 
63         PackageManager pm = mContext.getPackageManager();
64         List<ResolveInfo> infoList = pm.queryIntentActivities(
65                 new Intent(ACTION_TV_BOOT_COMPLETED), 0);
66         if (infoList != null) {
67             for (ResolveInfo resolveInfo : infoList) {
68                 if (isSystemApp(resolveInfo)) {
69                     Intent intent = new Intent();
70                     intent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,
71                             resolveInfo.activityInfo.name));
72                     return intent;
73                 }
74             }
75         }
76 
77         onSystemUpdateCheckerComplete();
78         return null;
79     }
80 
onSystemUpdateCheckerComplete()81     void onSystemUpdateCheckerComplete() {
82         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
83         prefs.edit().putInt(PREF_SYSTEM_CHECKED_BOOT_COUNT, getBootCount()).apply();
84     }
85 
getBootCount()86     private int getBootCount() {
87         // This API is available on Android N+
88         return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BOOT_COUNT, 0);
89     }
90 
isSystemApp(ResolveInfo info)91     private static boolean isSystemApp(ResolveInfo info) {
92         return (info.activityInfo != null && info.activityInfo.applicationInfo != null &&
93                 (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
94     }
95 }
96