Home | History | Annotate | Download | only in device
      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.tv.settings.device;
     18 
     19 import android.content.Context;
     20 import android.content.pm.PackageManager;
     21 import android.content.pm.ResolveInfo;
     22 import android.content.res.Resources;
     23 import android.media.tv.TvInputInfo;
     24 import android.media.tv.TvInputManager;
     25 import android.os.Bundle;
     26 import android.os.UserHandle;
     27 import android.support.annotation.Keep;
     28 import android.support.annotation.VisibleForTesting;
     29 import android.support.v7.preference.Preference;
     30 import android.text.TextUtils;
     31 import android.util.Log;
     32 import android.view.inputmethod.InputMethodInfo;
     33 
     34 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     35 import com.android.settingslib.applications.DefaultAppInfo;
     36 import com.android.settingslib.development.DevelopmentSettingsEnabler;
     37 import com.android.settingslib.wrapper.PackageManagerWrapper;
     38 import com.android.tv.settings.MainFragment;
     39 import com.android.tv.settings.R;
     40 import com.android.tv.settings.SettingsPreferenceFragment;
     41 import com.android.tv.settings.autofill.AutofillHelper;
     42 import com.android.tv.settings.device.sound.SoundFragment;
     43 import com.android.tv.settings.inputmethod.InputMethodHelper;
     44 import com.android.tv.settings.system.SecurityFragment;
     45 
     46 import java.util.List;
     47 
     48 /**
     49  * The "Device Preferences" screen in TV settings.
     50  */
     51 @Keep
     52 public class DevicePrefFragment extends SettingsPreferenceFragment {
     53     private static final String TAG = "DeviceFragment";
     54 
     55     @VisibleForTesting
     56     static final String KEY_DEVELOPER = "developer";
     57     private static final String KEY_USAGE = "usageAndDiag";
     58     private static final String KEY_INPUTS = "inputs";
     59     private static final String KEY_SOUNDS = "sound_effects";
     60     @VisibleForTesting
     61     static final String KEY_CAST_SETTINGS = "cast";
     62     private static final String KEY_GOOGLE_SETTINGS = "google_settings";
     63     private static final String KEY_HOME_SETTINGS = "home";
     64     @VisibleForTesting
     65     static final String KEY_KEYBOARD = "keyboard";
     66 
     67     private Preference mSoundsPref;
     68     private boolean mInputSettingNeeded;
     69     private PackageManagerWrapper mPm;
     70 
     71     @Override
     72     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
     73         if (isRestricted()) {
     74             setPreferencesFromResource(R.xml.device_restricted, null);
     75         } else {
     76             setPreferencesFromResource(R.xml.device, null);
     77         }
     78         mSoundsPref = findPreference(KEY_SOUNDS);
     79         final Preference inputPref = findPreference(KEY_INPUTS);
     80         if (inputPref != null) {
     81             inputPref.setVisible(mInputSettingNeeded);
     82         }
     83     }
     84 
     85     @Override
     86     public void onCreate(Bundle savedInstanceState) {
     87         final TvInputManager manager = (TvInputManager) getContext().getSystemService(
     88                 Context.TV_INPUT_SERVICE);
     89         if (manager != null) {
     90             for (final TvInputInfo input : manager.getTvInputList()) {
     91                 if (input.isPassthroughInput()) {
     92                     mInputSettingNeeded = true;
     93                 }
     94             }
     95         }
     96         super.onCreate(savedInstanceState);
     97     }
     98 
     99     @Override
    100     public void onAttach(Context context) {
    101         super.onAttach(context);
    102         mPm = new PackageManagerWrapper(context.getPackageManager());
    103     }
    104 
    105     @Override
    106     public void onResume() {
    107         super.onResume();
    108 
    109         updateDeveloperOptions();
    110         updateSounds();
    111         updateGoogleSettings();
    112         updateCastSettings();
    113         updateKeyboardAutofillSettings();
    114         hideIfIntentUnhandled(findPreference(KEY_HOME_SETTINGS));
    115         hideIfIntentUnhandled(findPreference(KEY_CAST_SETTINGS));
    116         hideIfIntentUnhandled(findPreference(KEY_USAGE));
    117     }
    118 
    119     @Override
    120     public int getMetricsCategory() {
    121         return MetricsEvent.SETTINGS_TV_DEVICE_CATEGORY;
    122     }
    123 
    124     private void hideIfIntentUnhandled(Preference preference) {
    125         if (preference == null || !preference.isVisible()) {
    126             return;
    127         }
    128         preference.setVisible(
    129                 MainFragment.systemIntentIsHandled(getContext(), preference.getIntent()) != null);
    130     }
    131 
    132     private boolean isRestricted() {
    133         return SecurityFragment.isRestrictedProfileInEffect(getContext());
    134     }
    135 
    136     @VisibleForTesting
    137     void updateDeveloperOptions() {
    138         final Preference developerPref = findPreference(KEY_DEVELOPER);
    139         if (developerPref == null) {
    140             return;
    141         }
    142 
    143         developerPref.setVisible(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(
    144                 getContext()));
    145     }
    146 
    147     private void updateSounds() {
    148         if (mSoundsPref == null) {
    149             return;
    150         }
    151 
    152         mSoundsPref.setIcon(SoundFragment.getSoundEffectsEnabled(getContext().getContentResolver())
    153                 ? R.drawable.ic_volume_up : R.drawable.ic_volume_off);
    154     }
    155 
    156     private void updateGoogleSettings() {
    157         final Preference googleSettingsPref = findPreference(KEY_GOOGLE_SETTINGS);
    158         if (googleSettingsPref != null) {
    159             final ResolveInfo info = MainFragment.systemIntentIsHandled(getContext(),
    160                     googleSettingsPref.getIntent());
    161             googleSettingsPref.setVisible(info != null);
    162             if (info != null && info.activityInfo != null) {
    163                 googleSettingsPref.setIcon(
    164                         info.activityInfo.loadIcon(getContext().getPackageManager()));
    165                 googleSettingsPref.setTitle(
    166                         info.activityInfo.loadLabel(getContext().getPackageManager()));
    167             }
    168         }
    169     }
    170 
    171     @VisibleForTesting
    172     void updateCastSettings() {
    173         final Preference castPref = findPreference(KEY_CAST_SETTINGS);
    174         if (castPref != null) {
    175             final ResolveInfo info = MainFragment.systemIntentIsHandled(
    176                         getContext(), castPref.getIntent());
    177             if (info != null) {
    178                 try {
    179                     final Context targetContext = getContext()
    180                             .createPackageContext(info.resolvePackageName != null
    181                                     ? info.resolvePackageName : info.activityInfo.packageName, 0);
    182                     castPref.setIcon(targetContext.getDrawable(info.getIconResource()));
    183                 } catch (Resources.NotFoundException | PackageManager.NameNotFoundException
    184                         | SecurityException e) {
    185                     Log.e(TAG, "Cast settings icon not found", e);
    186                 }
    187                 castPref.setTitle(info.activityInfo.loadLabel(getContext().getPackageManager()));
    188             }
    189         }
    190     }
    191 
    192     @VisibleForTesting
    193     void updateKeyboardAutofillSettings() {
    194         final Preference keyboardPref = findPreference(KEY_KEYBOARD);
    195 
    196         List<DefaultAppInfo> candidates = AutofillHelper.getAutofillCandidates(getContext(),
    197                 mPm, UserHandle.myUserId());
    198 
    199         // Switch title depends on whether there is autofill
    200         if (candidates.isEmpty()) {
    201             keyboardPref.setTitle(R.string.system_keyboard);
    202         } else {
    203             keyboardPref.setTitle(R.string.system_keyboard_autofill);
    204         }
    205 
    206         CharSequence summary = "";
    207         // append current keyboard to summary
    208         String defaultImId = InputMethodHelper.getDefaultInputMethodId(getContext());
    209         if (!TextUtils.isEmpty(defaultImId)) {
    210             InputMethodInfo info = InputMethodHelper.findInputMethod(defaultImId,
    211                     InputMethodHelper.getEnabledSystemInputMethodList(getContext()));
    212             if (info != null) {
    213                 summary = info.loadLabel(getContext().getPackageManager());
    214             }
    215 
    216         }
    217         // append current autofill to summary
    218         DefaultAppInfo appInfo = AutofillHelper.getCurrentAutofill(getContext(), candidates);
    219         if (appInfo != null) {
    220             CharSequence autofillInfo = appInfo.loadLabel();
    221             if (summary.length() > 0) {
    222                 getContext().getString(R.string.string_concat, summary, autofillInfo);
    223             } else {
    224                 summary = autofillInfo;
    225             }
    226         }
    227         keyboardPref.setSummary(summary);
    228     }
    229 }
    230