• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.settings.system;
17 
18 import static android.content.Context.CARRIER_CONFIG_SERVICE;
19 import static android.content.Context.SYSTEM_UPDATE_SERVICE;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.os.Build;
24 import android.os.Bundle;
25 import android.os.PersistableBundle;
26 import android.os.SystemUpdateManager;
27 import android.os.UserManager;
28 import android.telephony.CarrierConfigManager;
29 import android.text.TextUtils;
30 import android.util.Log;
31 
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceScreen;
34 
35 import com.android.settings.R;
36 import com.android.settings.Utils;
37 import com.android.settings.core.BasePreferenceController;
38 
39 import java.util.concurrent.ExecutionException;
40 import java.util.concurrent.FutureTask;
41 
42 public class SystemUpdatePreferenceController extends BasePreferenceController {
43 
44     private static final String TAG = "SysUpdatePrefContr";
45 
46     private static final String KEY_SYSTEM_UPDATE_SETTINGS = "system_update_settings";
47 
48     private final UserManager mUm;
49     private final SystemUpdateManager mUpdateManager;
50 
SystemUpdatePreferenceController(Context context)51     public SystemUpdatePreferenceController(Context context) {
52         super(context, KEY_SYSTEM_UPDATE_SETTINGS);
53         mUm = UserManager.get(context);
54         mUpdateManager = (SystemUpdateManager) context.getSystemService(SYSTEM_UPDATE_SERVICE);
55     }
56 
57     @Override
getAvailabilityStatus()58     public int getAvailabilityStatus() {
59         return mContext.getResources().getBoolean(R.bool.config_show_system_update_settings)
60                 && mUm.isAdminUser()
61                 ? AVAILABLE
62                 : UNSUPPORTED_ON_DEVICE;
63     }
64 
65     @Override
displayPreference(PreferenceScreen screen)66     public void displayPreference(PreferenceScreen screen) {
67         super.displayPreference(screen);
68         if (isAvailable()) {
69             Utils.updatePreferenceToSpecificActivityOrRemove(mContext, screen,
70                     getPreferenceKey(),
71                     Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
72         }
73     }
74 
75     @Override
handlePreferenceTreeClick(Preference preference)76     public boolean handlePreferenceTreeClick(Preference preference) {
77         if (TextUtils.equals(getPreferenceKey(), preference.getKey())) {
78             CarrierConfigManager configManager =
79                     (CarrierConfigManager) mContext.getSystemService(CARRIER_CONFIG_SERVICE);
80             PersistableBundle b = configManager.getConfig();
81             if (b != null && b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
82                 ciActionOnSysUpdate(b);
83             }
84         }
85         // always return false here because this handler does not want to block other handlers.
86         return false;
87     }
88 
89     @Override
getSummary()90     public CharSequence getSummary() {
91         CharSequence summary = mContext.getString(R.string.android_version_summary,
92                 Build.VERSION.RELEASE);
93         final FutureTask<Bundle> bundleFutureTask = new FutureTask<>(
94                 // Put the API call in a future to avoid StrictMode violation.
95                 () -> mUpdateManager.retrieveSystemUpdateInfo());
96         final Bundle updateInfo;
97         try {
98             bundleFutureTask.run();
99             updateInfo = bundleFutureTask.get();
100         } catch (InterruptedException | ExecutionException e) {
101             Log.w(TAG, "Error getting system update info.");
102             return summary;
103         }
104         switch (updateInfo.getInt(SystemUpdateManager.KEY_STATUS)) {
105             case SystemUpdateManager.STATUS_WAITING_DOWNLOAD:
106             case SystemUpdateManager.STATUS_IN_PROGRESS:
107             case SystemUpdateManager.STATUS_WAITING_INSTALL:
108             case SystemUpdateManager.STATUS_WAITING_REBOOT:
109                 summary = mContext.getText(R.string.android_version_pending_update_summary);
110                 break;
111             case SystemUpdateManager.STATUS_UNKNOWN:
112                 Log.d(TAG, "Update statue unknown");
113                 // fall through to next branch
114             case SystemUpdateManager.STATUS_IDLE:
115                 final String version = updateInfo.getString(SystemUpdateManager.KEY_TITLE);
116                 if (!TextUtils.isEmpty(version)) {
117                     summary = mContext.getString(R.string.android_version_summary, version);
118                 }
119                 break;
120         }
121         return summary;
122     }
123 
124     /**
125      * Trigger client initiated action (send intent) on system update
126      */
ciActionOnSysUpdate(PersistableBundle b)127     private void ciActionOnSysUpdate(PersistableBundle b) {
128         String intentStr = b.getString(CarrierConfigManager.
129                 KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
130         if (!TextUtils.isEmpty(intentStr)) {
131             String extra = b.getString(CarrierConfigManager.
132                     KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
133             String extraVal = b.getString(CarrierConfigManager.
134                     KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);
135 
136             Intent intent = new Intent(intentStr);
137             if (!TextUtils.isEmpty(extra)) {
138                 intent.putExtra(extra, extraVal);
139             }
140             Log.d(TAG, "ciActionOnSysUpdate: broadcasting intent " + intentStr +
141                     " with extra " + extra + ", " + extraVal);
142             intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
143             mContext.getApplicationContext().sendBroadcast(intent);
144         }
145     }
146 }
147