1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.settings.deviceinfo.legal;
16 
17 import android.content.Context;
18 import android.content.Intent;
19 import android.content.pm.ApplicationInfo;
20 import android.content.pm.PackageManager;
21 import android.content.pm.ResolveInfo;
22 
23 import androidx.preference.Preference;
24 import androidx.preference.PreferenceScreen;
25 
26 import com.android.settings.core.BasePreferenceController;
27 
28 import java.util.List;
29 
30 public abstract class LegalPreferenceController extends BasePreferenceController {
31     private final PackageManager mPackageManager;
32     private Preference mPreference;
33 
LegalPreferenceController(Context context, String key)34     public LegalPreferenceController(Context context, String key) {
35         super(context, key);
36         mPackageManager = mContext.getPackageManager();
37     }
38 
39     @Override
getAvailabilityStatus()40     public int getAvailabilityStatus() {
41         if (findMatchingSpecificActivity() != null) {
42             return AVAILABLE;
43         } else {
44             return UNSUPPORTED_ON_DEVICE;
45         }
46     }
47 
48     @Override
displayPreference(PreferenceScreen screen)49     public void displayPreference(PreferenceScreen screen) {
50         mPreference = screen.findPreference(getPreferenceKey());
51         super.displayPreference(screen);
52 
53         if (getAvailabilityStatus() == AVAILABLE) {
54             replacePreferenceIntent();
55         }
56     }
57 
getIntent()58     protected abstract Intent getIntent();
59 
findMatchingSpecificActivity()60     private ResolveInfo findMatchingSpecificActivity() {
61         final Intent intent = getIntent();
62         if (intent == null) {
63             return null;
64         }
65 
66         // Find the activity that is in the system image
67         final List<ResolveInfo> list = mPackageManager.queryIntentActivities(intent, 0);
68         if (list == null) {
69             return null;
70         }
71 
72         for (ResolveInfo resolveInfo : list) {
73             if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
74                     != 0) {
75                 return resolveInfo;
76             }
77         }
78 
79         // Did not find a matching activity
80         return null;
81     }
82 
replacePreferenceIntent()83     private void replacePreferenceIntent() {
84         final ResolveInfo resolveInfo = findMatchingSpecificActivity();
85         if (resolveInfo == null) {
86             return;
87         }
88 
89         // Replace the intent with this specific activity
90         mPreference.setIntent(new Intent()
91                 .setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name)
92                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
93 
94         mPreference.setTitle(resolveInfo.loadLabel(mPackageManager));
95     }
96 }
97