1 /*
2  * Copyright (C) 2019 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.phone.testapps.smsmanagertestapp;
18 
19 import android.Manifest;
20 import android.app.Activity;
21 import android.app.PendingIntent;
22 import android.content.ActivityNotFoundException;
23 import android.content.ComponentName;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.os.Bundle;
27 import android.telephony.SmsManager;
28 import android.telephony.SubscriptionManager;
29 import android.telephony.TelephonyManager;
30 import android.text.TextUtils;
31 import android.view.View;
32 import android.widget.EditText;
33 import android.widget.TextView;
34 import android.widget.Toast;
35 
36 /**
37  * Supports sending an SMS immediately and offloading the sending of the SMS to a background task.
38  */
39 public class SmsManagerTestApp extends Activity {
40 
41     private static final int REQUEST_PERMISSION_READ_STATE = 1;
42     private static final int REQUEST_GET_SMS_SUB_ID = 2;
43 
44     private static final ComponentName SETTINGS_SUB_PICK_ACTIVITY = new ComponentName(
45             "com.android.settings", "com.android.settings.sim.SimDialogActivity");
46 
47     // Can't import PERFORM_IMS_SINGLE_REGISTRATION const directly beause it's a @SystemApi
48     private static final String PERFORM_IMS_SINGLE_REGISTRATION =
49             "android.permission.PERFORM_IMS_SINGLE_REGISTRATION";
50 
51     /*
52      * Forwarded constants from SimDialogActivity.
53      */
54     private static final String DIALOG_TYPE_KEY = "dialog_type";
55     public static final String RESULT_SUB_ID = "result_sub_id";
56     private static final int SMS_PICK = 2;
57 
58     private static int sMessageId = 0;
59     private boolean mIsReadPhoneStateGranted = false;
60 
61     private EditText mPhoneNumber;
62 
63     @Override
onCreate(Bundle savedInstanceState)64     public void onCreate(Bundle savedInstanceState) {
65         super.onCreate(savedInstanceState);
66 
67         setContentView(R.layout.activity_main);
68 
69         findViewById(R.id.send_text_button).setOnClickListener(this::sendOutgoingSms);
70         findViewById(R.id.send_text_button_service)
71                 .setOnClickListener(this::sendOutgoingSmsService);
72         findViewById(R.id.get_sub_for_result_button).setOnClickListener(this::getSubIdForResult);
73         findViewById(R.id.enable_persistent_service)
74                 .setOnClickListener(this::setPersistentServiceComponentEnabled);
75         findViewById(R.id.disable_persistent_service)
76                 .setOnClickListener(this::setPersistentServiceComponentDisabled);
77         findViewById(R.id.check_single_reg_permission)
78                 .setOnClickListener(this::checkSingleRegPermission);
79         mPhoneNumber = (EditText) findViewById(R.id.phone_number_text);
80     }
81 
82     @Override
onResume()83     protected void onResume() {
84         super.onResume();
85         if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE)
86                 != PackageManager.PERMISSION_GRANTED
87                 || checkSelfPermission(Manifest.permission.SEND_SMS)
88                         != PackageManager.PERMISSION_GRANTED) {
89             mIsReadPhoneStateGranted = false;
90             requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE,
91                     Manifest.permission.SEND_SMS}, REQUEST_PERMISSION_READ_STATE);
92         } else {
93             mIsReadPhoneStateGranted = true;
94         }
95         if (mIsReadPhoneStateGranted) {
96             mPhoneNumber.setText(getPhoneNumber(), TextView.BufferType.NORMAL);
97         }
98     }
99 
100     @Override
onPause()101     protected void onPause() {
102         super.onPause();
103         stopService(new Intent(this, SmsManagerTestService.class));
104     }
105 
106     @Override
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)107     public void onRequestPermissionsResult(int requestCode, String[] permissions,
108             int[] grantResults) {
109         switch (requestCode) {
110             case REQUEST_PERMISSION_READ_STATE: {
111                 if (grantResults.length > 0
112                         && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
113                     mIsReadPhoneStateGranted = true;
114                 } else {
115                     // permission denied
116                     Toast.makeText(this, "read_phone_state denied.", Toast.LENGTH_SHORT).show();
117                 }
118             }
119 
120         }
121 
122         if (mIsReadPhoneStateGranted) {
123             mPhoneNumber.setText(getPhoneNumber(), TextView.BufferType.NORMAL);
124         }
125     }
126 
127     @Override
onActivityResult(int requestCode, int resultCode, Intent data)128     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
129         switch (requestCode) {
130             case (REQUEST_GET_SMS_SUB_ID) : {
131                 int resultSubId;
132                 if (resultCode == RESULT_OK) {
133                     resultSubId = data == null ? -1 : data.getIntExtra(RESULT_SUB_ID,
134                             SubscriptionManager.INVALID_SUBSCRIPTION_ID);
135                     Toast.makeText(this, "User picked sub id = " + resultSubId,
136                             Toast.LENGTH_LONG).show();
137                 } else {
138                     Toast.makeText(this, "User cancelled dialog.",
139                             Toast.LENGTH_SHORT).show();
140                 }
141                 break;
142             }
143         }
144     }
145 
146 
sendOutgoingSms(View view)147     private void sendOutgoingSms(View view) {
148         String phoneNumber = mPhoneNumber.getText().toString();
149         if (TextUtils.isEmpty(phoneNumber)) {
150             Toast.makeText(this, "Couldn't get phone number from view! Ignoring request...",
151                     Toast.LENGTH_SHORT).show();
152             return;
153         }
154         if (mIsReadPhoneStateGranted) {
155             SmsManager m = SmsManager.getDefault();
156             m.sendTextMessage(phoneNumber, null, "Test",
157                     PendingIntent.getBroadcast(this, sMessageId, getSendStatusIntent(), 0),
158                     null);
159             sMessageId++;
160         }
161     }
162 
sendOutgoingSmsService(View view)163     private void sendOutgoingSmsService(View view) {
164         String phoneNumber = mPhoneNumber.getText().toString();
165         if (TextUtils.isEmpty(phoneNumber)) {
166             Toast.makeText(this, "Couldn't get phone number from view! Ignoring request...",
167                     Toast.LENGTH_SHORT).show();
168             return;
169         }
170         if (mIsReadPhoneStateGranted) {
171             Intent sendSmsIntent = new Intent(SmsManagerTestService.SEND_SMS);
172             sendSmsIntent.putExtra(SmsManagerTestService.EXTRA_SEND_TEXT, "Text");
173             sendSmsIntent.putExtra(SmsManagerTestService.EXTRA_SEND_NUMBER, phoneNumber);
174             sendSmsIntent.putExtra(SmsManagerTestService.EXTRA_SEND_INTENT,
175                     PendingIntent.getBroadcast(this, sMessageId, getSendStatusIntent(), 0));
176             sendSmsIntent.setComponent(new ComponentName(this, SmsManagerTestService.class));
177             startService(sendSmsIntent);
178             sMessageId++;
179         }
180     }
getSubIdForResult(View view)181     private void getSubIdForResult(View view) {
182         // ask the user for a default SMS SIM.
183         Intent intent = new Intent();
184         intent.setComponent(SETTINGS_SUB_PICK_ACTIVITY);
185         intent.putExtra(DIALOG_TYPE_KEY, SMS_PICK);
186         try {
187             startActivity(intent, null);
188         } catch (ActivityNotFoundException anfe) {
189             // If Settings is not installed, only log the error as we do not want to break
190             // legacy applications.
191             Toast.makeText(this, "Unable to launch Settings application.",
192                     Toast.LENGTH_SHORT).show();
193         }
194     }
195 
setPersistentServiceComponentEnabled(View view)196     private void setPersistentServiceComponentEnabled(View view) {
197         getPackageManager().setComponentEnabledSetting(
198                 new ComponentName(this, PersistentService.class),
199                 PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
200                 PackageManager.DONT_KILL_APP);
201     }
202 
setPersistentServiceComponentDisabled(View view)203     private void setPersistentServiceComponentDisabled(View view) {
204         getPackageManager().setComponentEnabledSetting(
205                 new ComponentName(this, PersistentService.class),
206                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
207                 PackageManager.DONT_KILL_APP);
208     }
209 
checkSingleRegPermission(View view)210     private void checkSingleRegPermission(View view) {
211         if (checkSelfPermission(PERFORM_IMS_SINGLE_REGISTRATION)
212                 == PackageManager.PERMISSION_GRANTED) {
213             Toast.makeText(this, "Single Reg permission granted",
214                     Toast.LENGTH_SHORT).show();
215         } else {
216             Toast.makeText(this, "Single Reg permission NOT granted",
217                     Toast.LENGTH_SHORT).show();
218         }
219 
220     }
221 
getSendStatusIntent()222     private Intent getSendStatusIntent() {
223         // Encode requestId in intent data
224         return new Intent(SendStatusReceiver.MESSAGE_SENT_ACTION, null, this,
225                 SendStatusReceiver.class);
226     }
227 
getPhoneNumber()228     private String getPhoneNumber() {
229         String result = "6505551212";
230         int defaultSmsSub = SubscriptionManager.getDefaultSmsSubscriptionId();
231         if (mIsReadPhoneStateGranted) {
232             TelephonyManager tm = getSystemService(TelephonyManager.class);
233             if (tm != null) {
234                 tm = tm.createForSubscriptionId(defaultSmsSub);
235                 String line1Number = tm.getLine1Number();
236                 if (!TextUtils.isEmpty(line1Number)) {
237                     return line1Number;
238                 }
239             }
240         } else {
241             Toast.makeText(this, "Couldn't resolve line 1 due to permissions error.",
242                     Toast.LENGTH_LONG).show();
243         }
244         return result;
245     }
246 }
247