1 /* 2 * Copyright (C) 2016 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.bips.ui; 18 19 import android.app.AlertDialog; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.ServiceConnection; 24 import android.os.Bundle; 25 import android.os.IBinder; 26 import android.preference.Preference; 27 import android.preference.PreferenceCategory; 28 import android.preference.PreferenceFragment; 29 import android.preference.SwitchPreference; 30 import android.util.Log; 31 32 import com.android.bips.BuiltInPrintService; 33 import com.android.bips.P2pPermissionManager; 34 import com.android.bips.R; 35 import com.android.bips.discovery.DiscoveredPrinter; 36 import com.android.bips.p2p.P2pUtils; 37 38 /** 39 * Presents a list of printers and the ability to add a new one 40 */ 41 public class AddPrintersFragment extends PreferenceFragment implements ServiceConnection { 42 private static final String TAG = AddPrintersFragment.class.getSimpleName(); 43 private static final boolean DEBUG = false; 44 45 private static final String KEY_ADD_BY_IP = "add_by_ip"; 46 private static final String KEY_FIND_WIFI_DIRECT = "find_wifi_direct"; 47 private static final String KEY_WIFI_DIRECT_PRINTING = "wifi_direct_printing"; 48 private static final String KEY_SAVED_PRINTERS = "saved_printers"; 49 public static final String EXTRA_FIX_P2P_PERMISSION = "fix_p2p_permission"; 50 51 private static final int ORDER_SAVED = 2; 52 53 private PreferenceCategory mSavedPrintersCategory; 54 private Preference mAddPrinterByIpPreference; 55 private Preference mFindP2pPrintersPreference; 56 private SwitchPreference mP2pEnablePreference; 57 private BuiltInPrintService mPrintService; 58 private P2pPermissionManager mP2pPermissionManager; 59 60 @Override onCreate(Bundle in)61 public void onCreate(Bundle in) { 62 if (DEBUG) Log.d(TAG, "onCreate"); 63 super.onCreate(in); 64 addPreferencesFromResource(R.xml.add_printers_prefs); 65 mAddPrinterByIpPreference = getPreferenceScreen().findPreference(KEY_ADD_BY_IP); 66 67 mFindP2pPrintersPreference = getPreferenceScreen().findPreference( 68 KEY_FIND_WIFI_DIRECT); 69 mFindP2pPrintersPreference.setOnPreferenceClickListener(preference -> { 70 getFragmentManager().beginTransaction() 71 .replace(android.R.id.content, new FindP2pPrintersFragment()) 72 .addToBackStack(null) 73 .commit(); 74 return true; 75 }); 76 mP2pEnablePreference = (SwitchPreference) getPreferenceScreen() 77 .findPreference(KEY_WIFI_DIRECT_PRINTING); 78 mSavedPrintersCategory = (PreferenceCategory) getPreferenceScreen() 79 .findPreference(KEY_SAVED_PRINTERS); 80 } 81 82 @Override onStart()83 public void onStart() { 84 super.onStart(); 85 if (DEBUG) Log.d(TAG, "onStart"); 86 87 getActivity().setTitle(R.string.title_activity_add_printer); 88 getContext().bindService(new Intent(getContext(), BuiltInPrintService.class), this, 89 Context.BIND_AUTO_CREATE); 90 91 mP2pPermissionManager = new P2pPermissionManager(getActivity()); 92 updateP2pPreferences(); 93 94 if (getActivity().getIntent().getBooleanExtra(EXTRA_FIX_P2P_PERMISSION, false)) { 95 // Additional explanation is redundant, since the user saw it in notification. 96 mP2pPermissionManager.request(false, approve -> { 97 updateP2pPreferences(); 98 if (!approve) { 99 // The user is choosing to disable by denying Location. 100 mP2pPermissionManager.setState(P2pPermissionManager.State.DISABLED); 101 } 102 }); 103 } 104 105 mP2pEnablePreference.setOnPreferenceClickListener(preference -> { 106 if (mP2pEnablePreference.isChecked()) { 107 mP2pEnablePreference.setChecked(false); 108 if (mP2pPermissionManager.getState() == P2pPermissionManager.State.DISABLED) { 109 // We're no longer disabled, just denied 110 mP2pPermissionManager.setState(P2pPermissionManager.State.DENIED); 111 } 112 mP2pPermissionManager.reset(); 113 mP2pPermissionManager.request(true, approve -> updateP2pPreferences()); 114 } else { 115 // User disabled P2P 116 mP2pPermissionManager.setState(P2pPermissionManager.State.DISABLED); 117 updateP2pPreferences(); 118 } 119 return true; 120 }); 121 } 122 123 @Override onStop()124 public void onStop() { 125 super.onStop(); 126 if (DEBUG) Log.d(TAG, "onStop"); 127 128 getContext().unbindService(this); 129 } 130 131 @Override onServiceConnected(ComponentName componentName, IBinder iBinder)132 public void onServiceConnected(ComponentName componentName, IBinder iBinder) { 133 if (DEBUG) Log.d(TAG, "onServiceConnected"); 134 mPrintService = BuiltInPrintService.getInstance(); 135 136 mAddPrinterByIpPreference.setOnPreferenceClickListener(preference -> { 137 AlertDialog dialog = new AddManualPrinterDialog(getActivity(), 138 mPrintService.getManualDiscovery()); 139 dialog.setOnDismissListener(d -> updateSavedPrinters()); 140 dialog.show(); 141 return true; 142 }); 143 144 updateSavedPrinters(); 145 } 146 updateP2pPreferences()147 private void updateP2pPreferences() { 148 // Only allow the user to find new P2P printers when enabled 149 if (mP2pPermissionManager.isP2pEnabled()) { 150 mP2pEnablePreference.setChecked(true); 151 getPreferenceScreen().addPreference(mFindP2pPrintersPreference); 152 if (getActivity().getIntent().getBooleanExtra(EXTRA_FIX_P2P_PERMISSION, false)) { 153 // If we were only here to enable P2P permissions, go back to the print now. 154 getActivity().finish(); 155 } 156 } else { 157 mP2pEnablePreference.setChecked(false); 158 getPreferenceScreen().removePreference(mFindP2pPrintersPreference); 159 } 160 161 updateSavedPrinters(); 162 } 163 164 @Override onServiceDisconnected(ComponentName componentName)165 public void onServiceDisconnected(ComponentName componentName) { 166 mPrintService = null; 167 } 168 updateSavedPrinters()169 private void updateSavedPrinters() { 170 int savedCount = mPrintService == null ? 0 : mPrintService.getDiscovery() 171 .getSavedPrinters().size(); 172 173 if (savedCount == 0) { 174 if (getPreferenceScreen().findPreference(mSavedPrintersCategory.getKey()) != null) { 175 getPreferenceScreen().removePreference(mSavedPrintersCategory); 176 } 177 } else { 178 if (getPreferenceScreen().findPreference(mSavedPrintersCategory.getKey()) == null) { 179 getPreferenceScreen().addPreference(mSavedPrintersCategory); 180 } 181 182 mSavedPrintersCategory.removeAll(); 183 184 // With the service enumerate all saved printers 185 boolean p2pEnabled = mP2pPermissionManager.isP2pEnabled(); 186 for (DiscoveredPrinter printer : mPrintService.getDiscovery().getSavedPrinters()) { 187 // Don't show P2P printers while P2P is disabled. 188 if (P2pUtils.isP2p(printer) && !p2pEnabled) { 189 continue; 190 } 191 if (DEBUG) Log.d(TAG, "Adding saved printer " + printer); 192 PrinterPreference pref = new PrinterPreference(getContext(), mPrintService, 193 printer, false); 194 pref.setOrder(ORDER_SAVED); 195 pref.setOnPreferenceClickListener(preference -> { 196 showRemovalDialog(printer); 197 return true; 198 }); 199 mSavedPrintersCategory.addPreference(pref); 200 } 201 } 202 } 203 showRemovalDialog(DiscoveredPrinter printer)204 private void showRemovalDialog(DiscoveredPrinter printer) { 205 String message; 206 if (P2pUtils.isP2p(printer)) { 207 message = mPrintService.getString(R.string.connects_via_wifi_direct); 208 } else { 209 message = mPrintService.getString(R.string.connects_via_network, printer.path); 210 } 211 new AlertDialog.Builder(getContext()) 212 .setTitle(printer.name) 213 .setMessage(message) 214 .setNegativeButton(android.R.string.cancel, null) 215 .setPositiveButton(R.string.forget, (dialog, which) -> { 216 mPrintService.getDiscovery().removeSavedPrinter(printer.path); 217 updateSavedPrinters(); 218 }).show(); 219 } 220 } 221