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