1 /* 2 * Copyright (C) 2020 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.cts.useprocess; 18 19 import android.app.Service; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.os.Binder; 23 import android.os.IBinder; 24 import android.os.Parcel; 25 import android.os.Process; 26 import android.os.RemoteException; 27 import android.os.StrictMode; 28 import android.util.Log; 29 30 import java.io.IOException; 31 import java.io.InputStream; 32 import java.io.OutputStream; 33 import java.io.PrintWriter; 34 import java.io.StringWriter; 35 import java.net.ServerSocket; 36 import java.net.Socket; 37 import java.net.SocketException; 38 39 public class BaseNetworkService extends Service { 40 private static final String LOG_TAG = "ServiceWithInternet"; 41 42 public static final int TRANSACT_TEST = IBinder.FIRST_CALL_TRANSACTION; 43 44 final boolean mNetworkAllowed; 45 final String mExpectedProcessName; 46 readResult(Parcel in)47 public static final String readResult(Parcel in) { 48 if (in.readInt() != 0) { 49 return in.readString(); 50 } else { 51 return null; 52 } 53 } 54 readResultCallstack(Parcel in)55 public static final String readResultCallstack(Parcel in) { 56 return in.readString(); 57 } 58 writeResult(Parcel out, String errorMsg, Throwable where)59 static final void writeResult(Parcel out, String errorMsg, Throwable where) { 60 if (errorMsg != null) { 61 out.writeInt(1); 62 out.writeString(errorMsg); 63 if (where == null) { 64 where = new Exception(); 65 where.fillInStackTrace(); 66 } 67 StringWriter sw = new StringWriter(); 68 PrintWriter pw = new PrintWriter(sw, false); 69 where.printStackTrace(pw); 70 pw.flush(); 71 out.writeString(sw.toString()); 72 } else { 73 out.writeInt(0); 74 } 75 } 76 77 private final IBinder mBinder = new Binder() { 78 @Override 79 protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) 80 throws RemoteException { 81 if (code == TRANSACT_TEST) { 82 try { 83 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 84 .permitNetwork().build()); 85 doTest(reply); 86 } catch (Throwable e) { 87 writeResult(reply, "Unexpected exception: " + e, e); 88 } 89 return true; 90 } else { 91 return super.onTransact(code, data, reply, flags); 92 } 93 } 94 95 private void doTest(Parcel reply) { 96 if (!mExpectedProcessName.equals(getApplication().getProcessName())) { 97 writeResult(reply, 98 "Not running in correct process, expected " + mExpectedProcessName 99 + " but got " + getApplication().getProcessName(),null); 100 return; 101 } 102 103 try { 104 Socket socket = new Socket("example.com", 80); 105 socket.close(); 106 if (!mNetworkAllowed) { 107 writeResult(reply, 108 "Create inet socket did not throw SecurityException as expected", 109 null); 110 return; 111 } 112 } catch (SecurityException e) { 113 if (mNetworkAllowed) { 114 writeResult(reply, 115 "Create inet socket should be allowed but: " + e, e); 116 return; 117 } 118 } catch (IOException e) { 119 if (!mNetworkAllowed) { 120 writeResult(reply, 121 "Create inet socket did not throw SecurityException as expected", e); 122 return; 123 } 124 } 125 126 int hasPerm = checkPermission(android.Manifest.permission.INTERNET, 127 Process.myPid(), Process.myUid()); 128 if (mNetworkAllowed) { 129 if (hasPerm != PackageManager.PERMISSION_GRANTED) { 130 writeResult(reply, "Should have INTERNET permission, but got: " + hasPerm, 131 null); 132 return; 133 } 134 } else { 135 if (hasPerm != PackageManager.PERMISSION_DENIED) { 136 writeResult(reply, "Shouldn't have INTERNET permission, but got: " + hasPerm, 137 null); 138 return; 139 } 140 } 141 142 // A local socket binding is not allowed if you don't have network access, and 143 // also not allowed for instant aps. 144 final boolean allowLocalSocket = mNetworkAllowed 145 && !getPackageManager().isInstantApp(); 146 147 try { 148 // Transfer 128K of data across an explicitly localhost socket. 149 final int byteCount = 1024; 150 final int packetCount = 128; 151 final ServerSocket server; 152 try { 153 server = new ServerSocket(0); 154 if (!allowLocalSocket) { 155 server.close(); 156 writeResult(reply, 157 "Create local socket did not throw SecurityException as expected", 158 null); 159 return; 160 } 161 } catch (SocketException e) { 162 if (allowLocalSocket) { 163 writeResult(reply, 164 "Create local socket should be allowed but: " + e, null); 165 } 166 return; 167 } 168 new Thread("TrafficStatsTest.testTrafficStatsForLocalhost") { 169 @Override 170 public void run() { 171 try { 172 Socket socket = new Socket("localhost", server.getLocalPort()); 173 OutputStream out = socket.getOutputStream(); 174 byte[] buf = new byte[byteCount]; 175 for (int i = 0; i < packetCount; i++) { 176 out.write(buf); 177 out.flush(); 178 } 179 out.close(); 180 socket.close(); 181 } catch (IOException e) { 182 writeResult(reply, "Badness during writes to socket: " + e, e); 183 return; 184 } 185 } 186 }.start(); 187 188 int read = 0; 189 try { 190 Socket socket = server.accept(); 191 InputStream in = socket.getInputStream(); 192 byte[] buf = new byte[byteCount]; 193 while (read < byteCount * packetCount) { 194 int n = in.read(buf); 195 if (n <= 0) { 196 writeResult(reply, "Unexpected EOF @ " + read,null); 197 return; 198 } 199 read += n; 200 } 201 } finally { 202 server.close(); 203 } 204 if (read != (byteCount * packetCount)) { 205 writeResult(reply, "Not all data read back: expected " 206 + (byteCount * packetCount) + ", received" + read, null); 207 return; 208 209 } 210 } catch (IOException e) { 211 writeResult(reply, e.toString(), e); 212 return; 213 } 214 215 writeResult(reply, null, null); 216 } 217 }; 218 BaseNetworkService(boolean networkAllowed, String expectedProcessName)219 public BaseNetworkService(boolean networkAllowed, String expectedProcessName) { 220 mNetworkAllowed = networkAllowed; 221 mExpectedProcessName = expectedProcessName; 222 } 223 224 @Override onBind(Intent intent)225 public IBinder onBind(Intent intent) { 226 return mBinder; 227 } 228 } 229