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.tv.settings.overlay;
18 
19 import android.app.AppGlobals;
20 import android.app.admin.DevicePolicyManager;
21 import android.content.Context;
22 import android.net.ConnectivityManager;
23 import android.net.VpnManager;
24 import android.os.Bundle;
25 import android.os.UserManager;
26 import android.util.Log;
27 
28 import androidx.annotation.Keep;
29 import androidx.annotation.NonNull;
30 import androidx.fragment.app.Fragment;
31 import androidx.preference.Preference;
32 import androidx.preference.PreferenceFragmentCompat;
33 import androidx.preference.PreferenceScreen;
34 
35 import com.android.tv.settings.SettingsFragmentProvider;
36 import com.android.tv.settings.basic.BasicModeFeatureProvider;
37 import com.android.tv.settings.basic.BasicModeFeatureProviderImpl;
38 import com.android.tv.settings.enterprise.EnterprisePrivacyFeatureProvider;
39 import com.android.tv.settings.enterprise.EnterprisePrivacyFeatureProviderImpl;
40 import com.android.tv.settings.enterprise.apps.ApplicationFeatureProvider;
41 import com.android.tv.settings.enterprise.apps.ApplicationFeatureProviderImpl;
42 import com.android.tv.settings.help.SupportFeatureProvider;
43 import com.android.tv.settings.help.SupportFeatureProviderImpl;
44 import com.android.tv.settings.startup.StartupVerificationFeatureProvider;
45 import com.android.tv.settings.startup.StartupVerificationFeatureProviderImpl;
46 import com.android.tv.settings.system.LeanbackPickerDialogFragment;
47 import com.android.tv.settings.system.LeanbackPickerDialogPreference;
48 import com.android.tv.twopanelsettings.TwoPanelSettingsFragment;
49 
50 /** Two panel customized implementation of the feature factory. */
51 @Keep
52 public class FeatureFactoryImplTwoPanel implements FeatureFactory {
53 
54     protected static final String TAG = "FeatureFactoryImplTwoP";
55 
56     private EnterprisePrivacyFeatureProvider mEnterprisePrivacyFeatureProvider;
57     private ApplicationFeatureProvider mApplicationFeatureProvider;
58 
59     @Override
getSettingsFragmentProvider()60     public SettingsFragmentProvider getSettingsFragmentProvider() {
61         return SettingsFragment::newInstance;
62     }
63 
64     @Override
getSupportFeatureProvider()65     public SupportFeatureProvider getSupportFeatureProvider() {
66         return new SupportFeatureProviderImpl();
67     }
68 
69     @Override
getBasicModeFeatureProvider()70     public BasicModeFeatureProvider getBasicModeFeatureProvider() {
71         return new BasicModeFeatureProviderImpl();
72     }
73 
74     @Override
getStartupVerificationFeatureProvider()75     public StartupVerificationFeatureProvider getStartupVerificationFeatureProvider() {
76         return new StartupVerificationFeatureProviderImpl();
77     }
78 
79     @Override
getEnterprisePrivacyFeatureProvider(Context context)80     public EnterprisePrivacyFeatureProvider getEnterprisePrivacyFeatureProvider(Context context) {
81         if (mEnterprisePrivacyFeatureProvider == null) {
82             final Context appContext = context.getApplicationContext();
83             mEnterprisePrivacyFeatureProvider = new EnterprisePrivacyFeatureProviderImpl(appContext,
84                     appContext.getSystemService(DevicePolicyManager.class),
85                     appContext.getPackageManager(),
86                     UserManager.get(appContext),
87                     appContext.getSystemService(ConnectivityManager.class),
88                     appContext.getSystemService(VpnManager.class),
89                     appContext.getResources());
90         }
91         return mEnterprisePrivacyFeatureProvider;
92     }
93 
94     @Override
getApplicationFeatureProvider(Context context)95     public ApplicationFeatureProvider getApplicationFeatureProvider(Context context) {
96         if (mApplicationFeatureProvider == null) {
97             final Context appContext = context.getApplicationContext();
98             mApplicationFeatureProvider = new ApplicationFeatureProviderImpl(appContext,
99                     appContext.getPackageManager(),
100                     AppGlobals.getPackageManager(),
101                     appContext.getSystemService(DevicePolicyManager.class));
102         }
103         return mApplicationFeatureProvider;
104     }
105 
106     /**
107      * A settings fragment suitable for displaying in the two panel layout. Handles launching
108      * fragments and dialogs in a reasonably generic way.
109      */
110     public static class SettingsFragment extends TwoPanelSettingsFragment {
111 
112         private static final String EXTRA_FRAGMENT_CLASS_NAME = "fragmentClassName";
113 
SettingsFragment()114         public SettingsFragment() {}
115 
116         /** Constructs a new instance of a settings fragment. */
newInstance(String className, Bundle arguments)117         public static SettingsFragment newInstance(String className, Bundle arguments) {
118             SettingsFragment fragment = new SettingsFragment();
119             Bundle args = arguments == null ? new Bundle() : new Bundle(arguments);
120             args.putString(EXTRA_FRAGMENT_CLASS_NAME, className);
121             fragment.setArguments(args);
122             return fragment;
123         }
124 
125         @Override
onPreferenceStartScreen( PreferenceFragmentCompat caller, PreferenceScreen pref)126         public final boolean onPreferenceStartScreen(
127                 PreferenceFragmentCompat caller, PreferenceScreen pref) {
128             return false;
129         }
130 
131         @Override
onCreatePreviewFragment(@onNull Fragment caller, Preference pref)132         public Fragment onCreatePreviewFragment(@NonNull Fragment caller, Preference pref) {
133             Fragment f;
134             if (pref instanceof LeanbackPickerDialogPreference) {
135                 final LeanbackPickerDialogPreference dialogPreference =
136                         (LeanbackPickerDialogPreference) pref;
137                 f = dialogPreference.getType().equals("date")
138                         ? LeanbackPickerDialogFragment.newDatePickerInstance(pref.getKey())
139                         : LeanbackPickerDialogFragment.newTimePickerInstance(pref.getKey());
140                 f.setTargetFragment(caller, 0);
141                 return f;
142             } else {
143                 return super.onCreatePreviewFragment(caller, pref);
144             }
145         }
146 
147         @Override
onPreferenceStartInitialScreen()148         public void onPreferenceStartInitialScreen() {
149             try {
150                 String className = getArguments().getString(EXTRA_FRAGMENT_CLASS_NAME);
151                 final Fragment fragment = (Fragment) Class.forName(className).newInstance();
152                 fragment.setArguments(getArguments());
153                 startPreferenceFragment(fragment);
154             } catch (IllegalAccessException | ClassNotFoundException
155                     | java.lang.InstantiationException e) {
156                 Log.e(TAG, "Unable to start initial preference screen.", e);
157             }
158         }
159     }
160 }
161