1 /*
2  * Copyright (C) 2009 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.network.apn;
18 
19 import static com.android.settings.network.apn.ApnEditPageProviderKt.EDIT_URL;
20 
21 import android.content.ContentUris;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.net.Uri;
25 import android.provider.Telephony;
26 import android.telephony.SubscriptionManager;
27 import android.util.AttributeSet;
28 import android.util.Log;
29 import android.view.View;
30 import android.widget.CompoundButton;
31 import android.widget.RadioButton;
32 import android.widget.RelativeLayout;
33 import android.widget.Toast;
34 
35 import androidx.annotation.Nullable;
36 import androidx.preference.Preference;
37 import androidx.preference.PreferenceViewHolder;
38 
39 import com.android.settings.R;
40 import com.android.settings.flags.Flags;
41 import com.android.settings.spa.SpaActivity;
42 
43 /**
44  * Preference of APN UI entry
45  */
46 public class ApnPreference extends Preference
47         implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
48     private static final String TAG = "ApnPreference";
49     private boolean mIsChecked = false;
50     @Nullable
51     private RadioButton mRadioButton = null;
52     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
53     private boolean mProtectFromCheckedChange = false;
54     private boolean mDefaultSelectable = true;
55     private boolean mHideDetails = false;
56 
57     /**
58      * Constructor of Preference
59      */
ApnPreference(Context context, AttributeSet attrs, int defStyle)60     public ApnPreference(Context context, AttributeSet attrs, int defStyle) {
61         super(context, attrs, defStyle);
62         // Primary target and radio button could be selectable, but entire preference itself is not
63         // selectable.
64         setSelectable(false);
65     }
66 
67     /**
68      * Constructor of Preference
69      */
ApnPreference(Context context, AttributeSet attrs)70     public ApnPreference(Context context, AttributeSet attrs) {
71         this(context, attrs, R.attr.apnPreferenceStyle);
72     }
73 
74     /**
75      * Constructor of Preference
76      */
ApnPreference(Context context)77     public ApnPreference(Context context) {
78         this(context, null);
79     }
80 
81     @Override
onBindViewHolder(PreferenceViewHolder view)82     public void onBindViewHolder(PreferenceViewHolder view) {
83         super.onBindViewHolder(view);
84 
85         final RelativeLayout textArea = (RelativeLayout) view.findViewById(R.id.text_layout);
86         textArea.setOnClickListener(this);
87 
88         final RadioButton rb = view.itemView.requireViewById(R.id.apn_radiobutton);
89         mRadioButton = rb;
90         if (mDefaultSelectable) {
91             view.itemView.requireViewById(R.id.apn_radio_button_frame).setOnClickListener((v) -> {
92                 rb.performClick();
93             });
94             rb.setOnCheckedChangeListener(this);
95 
96             mProtectFromCheckedChange = true;
97             rb.setChecked(mIsChecked);
98             mProtectFromCheckedChange = false;
99             rb.setVisibility(View.VISIBLE);
100         } else {
101             rb.setVisibility(View.GONE);
102         }
103     }
104 
105     /**
106      * Set preference isChecked.
107      */
setIsChecked(boolean isChecked)108     public void setIsChecked(boolean isChecked) {
109         mIsChecked = isChecked;
110         if (mRadioButton != null) {
111             mProtectFromCheckedChange = true;
112             mRadioButton.setChecked(mIsChecked);
113             mProtectFromCheckedChange = false;
114         }
115     }
116 
117     /**
118      * Change the preference status.
119      */
onCheckedChanged(CompoundButton buttonView, boolean isChecked)120     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
121         Log.i(TAG, "ID: " + getKey() + " :" + isChecked);
122         if (mProtectFromCheckedChange) {
123             return;
124         }
125 
126         if (isChecked) {
127             callChangeListener(getKey());
128         }
129     }
130 
131     @Override
onClick(View layoutView)132     public void onClick(View layoutView) {
133         super.onClick();
134         final Context context = getContext();
135         final int pos = Integer.parseInt(getKey());
136         if (context == null) {
137             Log.w(TAG, "No context available for pos=" + pos);
138             return;
139         }
140 
141         if (mHideDetails) {
142             Toast.makeText(context, context.getString(R.string.cannot_change_apn_toast),
143                     Toast.LENGTH_LONG).show();
144             return;
145         }
146 
147         final Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
148 
149         if (Flags.newApnPageEnabled()) {
150             String route = ApnEditPageProvider.INSTANCE.getRoute(EDIT_URL, url, mSubId);
151             SpaActivity.startSpaActivity(context, route);
152         } else {
153             final Intent editIntent = new Intent(Intent.ACTION_EDIT, url);
154             editIntent.putExtra(ApnSettings.SUB_ID, mSubId);
155             editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
156             context.startActivity(editIntent);
157         }
158     }
159 
setDefaultSelectable(boolean defaultSelectable)160     public void setDefaultSelectable(boolean defaultSelectable) {
161         mDefaultSelectable = defaultSelectable;
162     }
163 
setSubId(int subId)164     public void setSubId(int subId) {
165         mSubId = subId;
166     }
167 
168     /**
169      * Hide details
170      */
setHideDetails()171     public void setHideDetails() {
172         mHideDetails = true;
173     }
174 }
175