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 package com.android.settings.network; 17 18 import static android.provider.SettingsSlicesContract.KEY_AIRPLANE_MODE; 19 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.net.Uri; 25 import android.provider.SettingsSlicesContract; 26 import android.telephony.TelephonyManager; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.fragment.app.Fragment; 30 import androidx.preference.Preference; 31 import androidx.preference.PreferenceScreen; 32 import androidx.preference.SwitchPreference; 33 34 import com.android.settings.AirplaneModeEnabler; 35 import com.android.settings.R; 36 import com.android.settings.core.TogglePreferenceController; 37 import com.android.settingslib.core.lifecycle.LifecycleObserver; 38 import com.android.settingslib.core.lifecycle.events.OnStart; 39 import com.android.settingslib.core.lifecycle.events.OnStop; 40 41 public class AirplaneModePreferenceController extends TogglePreferenceController 42 implements LifecycleObserver, OnStart, OnStop, 43 AirplaneModeEnabler.OnAirplaneModeChangedListener { 44 45 public static final int REQUEST_CODE_EXIT_ECM = 1; 46 47 /** 48 * Uri for Airplane mode Slice. 49 */ 50 public static final Uri SLICE_URI = new Uri.Builder() 51 .scheme(ContentResolver.SCHEME_CONTENT) 52 .authority(SettingsSlicesContract.AUTHORITY) 53 .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) 54 .appendPath(SettingsSlicesContract.KEY_AIRPLANE_MODE) 55 .build(); 56 private static final String EXIT_ECM_RESULT = "exit_ecm_result"; 57 58 private Fragment mFragment; 59 private AirplaneModeEnabler mAirplaneModeEnabler; 60 private SwitchPreference mAirplaneModePreference; 61 AirplaneModePreferenceController(Context context, String key)62 public AirplaneModePreferenceController(Context context, String key) { 63 super(context, key); 64 65 if (isAvailable(mContext)) { 66 mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, this); 67 } 68 } 69 setFragment(Fragment hostFragment)70 public void setFragment(Fragment hostFragment) { 71 mFragment = hostFragment; 72 } 73 74 @VisibleForTesting setAirplaneModeEnabler(AirplaneModeEnabler airplaneModeEnabler)75 void setAirplaneModeEnabler(AirplaneModeEnabler airplaneModeEnabler) { 76 mAirplaneModeEnabler = airplaneModeEnabler; 77 } 78 79 @Override handlePreferenceTreeClick(Preference preference)80 public boolean handlePreferenceTreeClick(Preference preference) { 81 if (KEY_AIRPLANE_MODE.equals(preference.getKey()) 82 && mAirplaneModeEnabler.isInEcmMode()) { 83 // In ECM mode launch ECM app dialog 84 if (mFragment != null) { 85 mFragment.startActivityForResult( 86 new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null), 87 REQUEST_CODE_EXIT_ECM); 88 } 89 return true; 90 } 91 92 return false; 93 } 94 95 @Override getSliceUri()96 public Uri getSliceUri() { 97 return SLICE_URI; 98 } 99 100 @Override displayPreference(PreferenceScreen screen)101 public void displayPreference(PreferenceScreen screen) { 102 super.displayPreference(screen); 103 mAirplaneModePreference = screen.findPreference(getPreferenceKey()); 104 } 105 isAvailable(Context context)106 public static boolean isAvailable(Context context) { 107 return context.getResources().getBoolean(R.bool.config_show_toggle_airplane) 108 && !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); 109 } 110 111 @Override isPublicSlice()112 public boolean isPublicSlice() { 113 return true; 114 } 115 116 @Override 117 @AvailabilityStatus getAvailabilityStatus()118 public int getAvailabilityStatus() { 119 return isAvailable(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; 120 } 121 122 @Override onStart()123 public void onStart() { 124 if (isAvailable()) { 125 mAirplaneModeEnabler.start(); 126 } 127 } 128 129 @Override onStop()130 public void onStop() { 131 if (isAvailable()) { 132 mAirplaneModeEnabler.stop(); 133 } 134 } 135 onActivityResult(int requestCode, int resultCode, Intent data)136 public void onActivityResult(int requestCode, int resultCode, Intent data) { 137 if (requestCode == REQUEST_CODE_EXIT_ECM) { 138 final boolean isChoiceYes = data.getBooleanExtra(EXIT_ECM_RESULT, false); 139 // Set Airplane mode based on the return value and checkbox state 140 mAirplaneModeEnabler.setAirplaneModeInECM(isChoiceYes, 141 mAirplaneModePreference.isChecked()); 142 } 143 } 144 145 @Override isChecked()146 public boolean isChecked() { 147 return mAirplaneModeEnabler.isAirplaneModeOn(); 148 } 149 150 @Override setChecked(boolean isChecked)151 public boolean setChecked(boolean isChecked) { 152 if (isChecked() == isChecked) { 153 return false; 154 } 155 mAirplaneModeEnabler.setAirplaneMode(isChecked); 156 return true; 157 } 158 159 @Override onAirplaneModeChanged(boolean isAirplaneModeOn)160 public void onAirplaneModeChanged(boolean isAirplaneModeOn) { 161 if (mAirplaneModePreference != null) { 162 mAirplaneModePreference.setChecked(isAirplaneModeOn); 163 } 164 } 165 } 166