1 /*
2  * Copyright (C) 2020 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.settings.display;
18 
19 import static android.os.UserManager.DISALLOW_SET_WALLPAPER;
20 
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ResolveInfo;
26 import android.os.UserHandle;
27 import android.text.TextUtils;
28 import android.util.Log;
29 
30 import androidx.preference.Preference;
31 import androidx.preference.PreferenceScreen;
32 
33 import com.android.settings.R;
34 import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
35 import com.android.settings.activityembedding.ActivityEmbeddingUtils;
36 import com.android.settings.core.BasePreferenceController;
37 import com.android.settingslib.RestrictedLockUtilsInternal;
38 import com.android.settingslib.RestrictedTopLevelPreference;
39 
40 import java.util.List;
41 
42 /** This controller manages the wallpaper preference of the top level page. */
43 public class TopLevelWallpaperPreferenceController extends BasePreferenceController {
44     private static final String TAG = "TopLevelWallpaperPreferenceController";
45     private static final String LAUNCHED_SETTINGS = "app_launched_settings";
46 
47     private final String mWallpaperPackage;
48     private final String mWallpaperClass;
49     private final String mStylesAndWallpaperClass;
50     private final String mWallpaperLaunchExtra;
51 
TopLevelWallpaperPreferenceController(Context context, String key)52     public TopLevelWallpaperPreferenceController(Context context, String key) {
53         super(context, key);
54         mWallpaperPackage = mContext.getString(R.string.config_wallpaper_picker_package);
55         mWallpaperClass = mContext.getString(R.string.config_wallpaper_picker_class);
56         mStylesAndWallpaperClass =
57                 mContext.getString(R.string.config_styles_and_wallpaper_picker_class);
58         mWallpaperLaunchExtra = mContext.getString(R.string.config_wallpaper_picker_launch_extra);
59     }
60 
61     @Override
displayPreference(PreferenceScreen screen)62     public void displayPreference(PreferenceScreen screen) {
63         super.displayPreference(screen);
64         Preference preference = screen.findPreference(getPreferenceKey());
65         preference.setTitle(getTitle());
66         ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
67                 mContext,
68                 getComponentName(),
69                 null /* secondaryIntentAction */,
70                 true /* clearTop */);
71     }
72 
getTitle()73     public String getTitle() {
74         return mContext.getString(areStylesAvailable()
75                 ? R.string.style_and_wallpaper_settings_title : R.string.wallpaper_settings_title);
76     }
77 
getComponentName()78     public ComponentName getComponentName() {
79         return new ComponentName(mWallpaperPackage, getComponentClassString());
80     }
81 
getComponentClassString()82     public String getComponentClassString() {
83         return areStylesAvailable() ? mStylesAndWallpaperClass : mWallpaperClass;
84     }
85 
86     @Override
getAvailabilityStatus()87     public int getAvailabilityStatus() {
88         if ((TextUtils.isEmpty(mWallpaperClass) && TextUtils.isEmpty(mStylesAndWallpaperClass))
89                 || TextUtils.isEmpty(mWallpaperPackage)) {
90             Log.e(TAG, "No Wallpaper picker specified!");
91             return UNSUPPORTED_ON_DEVICE;
92         }
93         return canResolveWallpaperComponent(getComponentClassString())
94                 ? AVAILABLE_UNSEARCHABLE : CONDITIONALLY_UNAVAILABLE;
95     }
96 
97     @Override
updateState(Preference preference)98     public void updateState(Preference preference) {
99         disablePreferenceIfManaged((RestrictedTopLevelPreference) preference);
100     }
101 
102     @Override
handlePreferenceTreeClick(Preference preference)103     public boolean handlePreferenceTreeClick(Preference preference) {
104         if (getPreferenceKey().equals(preference.getKey())) {
105             final Intent intent = new Intent().setComponent(
106                     getComponentName()).putExtra(mWallpaperLaunchExtra, LAUNCHED_SETTINGS);
107             if (areStylesAvailable() && !ActivityEmbeddingUtils.isEmbeddingActivityEnabled(
108                     mContext)) {
109                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
110             }
111             preference.getContext().startActivity(intent);
112             return true;
113         }
114         return super.handlePreferenceTreeClick(preference);
115     }
116 
117     /** Returns whether Styles & Wallpaper is enabled and available. */
areStylesAvailable()118     public boolean areStylesAvailable() {
119         return !TextUtils.isEmpty(mStylesAndWallpaperClass)
120                 && canResolveWallpaperComponent(mStylesAndWallpaperClass);
121     }
122 
canResolveWallpaperComponent(String className)123     private boolean canResolveWallpaperComponent(String className) {
124         final ComponentName componentName = new ComponentName(mWallpaperPackage, className);
125         final PackageManager pm = mContext.getPackageManager();
126         final Intent intent = new Intent().setComponent(componentName);
127         final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0 /* flags */);
128         return resolveInfos != null && !resolveInfos.isEmpty();
129     }
130 
disablePreferenceIfManaged(RestrictedTopLevelPreference pref)131     private void disablePreferenceIfManaged(RestrictedTopLevelPreference pref) {
132         final String restriction = DISALLOW_SET_WALLPAPER;
133         if (pref != null) {
134             pref.setDisabledByAdmin(null);
135             if (RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
136                     restriction, UserHandle.myUserId())) {
137                 // Do not show the admin dialog for system restriction.
138                 pref.setEnabled(false);
139             } else {
140                 pref.checkRestrictionAndSetDisabled(restriction);
141             }
142         }
143     }
144 }
145