• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.car.settings.system;
18 
19 import android.car.drivingstate.CarUxRestrictions;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.ApplicationInfo;
23 import android.content.pm.PackageManager;
24 import android.content.pm.ResolveInfo;
25 import android.os.PersistableBundle;
26 import android.os.UserManager;
27 import android.telephony.CarrierConfigManager;
28 import android.text.TextUtils;
29 
30 import androidx.preference.Preference;
31 
32 import com.android.car.settings.R;
33 import com.android.car.settings.common.FragmentController;
34 import com.android.car.settings.common.Logger;
35 import com.android.car.settings.common.PreferenceController;
36 
37 import java.util.List;
38 
39 /**
40  * Controller which determines if the system update preference should be displayed based on
41  * device and user status. When the preference is clicked, this controller broadcasts a client
42  * initiated action if an intent is available in carrier-specific telephony configuration.
43  *
44  * @see CarrierConfigManager#KEY_CI_ACTION_ON_SYS_UPDATE_BOOL
45  */
46 public class SystemUpdatePreferenceController extends PreferenceController<Preference> {
47 
48     private static final Logger LOG = new Logger(SystemUpdatePreferenceController.class);
49 
50     private final UserManager mUserManager;
51     private boolean mActivityFound;
52 
SystemUpdatePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)53     public SystemUpdatePreferenceController(Context context, String preferenceKey,
54             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
55         super(context, preferenceKey, fragmentController, uxRestrictions);
56         mUserManager = UserManager.get(context);
57     }
58 
59     @Override
getPreferenceType()60     protected Class<Preference> getPreferenceType() {
61         return Preference.class;
62     }
63 
64     @Override
getAvailabilityStatus()65     protected int getAvailabilityStatus() {
66         if (!getContext().getResources().getBoolean(R.bool.config_show_system_update_settings)) {
67             return UNSUPPORTED_ON_DEVICE;
68         }
69         return mUserManager.isAdminUser() ? AVAILABLE : DISABLED_FOR_PROFILE;
70     }
71 
72     @Override
onCreateInternal()73     protected void onCreateInternal() {
74         Preference preference = getPreference();
75         Intent intent = preference.getIntent();
76         if (intent != null) {
77             // Find the activity that is in the system image.
78             PackageManager pm = getContext().getPackageManager();
79             List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
80             int listSize = list.size();
81             for (int i = 0; i < listSize; i++) {
82                 ResolveInfo resolveInfo = list.get(i);
83                 if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
84                         != 0) {
85                     // Replace the intent with this specific activity.
86                     preference.setIntent(
87                             new Intent().setClassName(resolveInfo.activityInfo.packageName,
88                                     resolveInfo.activityInfo.name));
89                     // Set the preference title to the activity's label.
90                     preference.setTitle(resolveInfo.loadLabel(pm));
91                     mActivityFound = true;
92                 }
93             }
94         }
95     }
96 
97     @Override
updateState(Preference preference)98     protected void updateState(Preference preference) {
99         preference.setVisible(mActivityFound);
100     }
101 
102     @Override
handlePreferenceClicked(Preference preference)103     protected boolean handlePreferenceClicked(Preference preference) {
104         CarrierConfigManager configManager = getContext().getSystemService(
105                 CarrierConfigManager.class);
106         PersistableBundle b = configManager.getConfig();
107         if (b != null && b.getBoolean(CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_BOOL)) {
108             ciActionOnSysUpdate(b);
109         }
110         // Don't handle so that preference framework will launch the preference intent.
111         return false;
112     }
113 
114     /** Trigger client initiated action (send intent) on system update. */
ciActionOnSysUpdate(PersistableBundle b)115     private void ciActionOnSysUpdate(PersistableBundle b) {
116         String intentStr = b.getString(
117                 CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING);
118         if (!TextUtils.isEmpty(intentStr)) {
119             String extra = b.getString(
120                     CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING);
121             String extraVal = b.getString(
122                     CarrierConfigManager.KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING);
123 
124             Intent intent = new Intent(intentStr);
125             if (!TextUtils.isEmpty(extra)) {
126                 intent.putExtra(extra, extraVal);
127             }
128             LOG.d("ciActionOnSysUpdate: broadcasting intent " + intentStr + " with extra " + extra
129                     + ", " + extraVal);
130             getContext().getApplicationContext().sendBroadcast(intent);
131         }
132     }
133 }
134