1 /* 2 * Copyright (C) 2008 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 android.app.stubs; 18 19 import android.app.Service; 20 import android.content.Context; 21 import android.content.Intent; 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 28 import com.android.compatibility.common.util.IBinderParcelable; 29 30 public class LocalService extends Service { 31 public static final String SERVICE_LOCAL = 32 "android.app.cts.activity.SERVICE_LOCAL"; 33 public static final String SERVICE_LOCAL_GRANTED = 34 "android.app.cts.activity.SERVICE_LOCAL_GRANTED"; 35 public static final String SERVICE_LOCAL_DENIED = 36 "android.app.cts.activity.SERVICE_LOCAL_DENIED"; 37 38 public static final String REPORT_OBJ_NAME = "report"; 39 40 public static final int STARTED_CODE = 1; 41 public static final int DESTROYED_CODE = 2; 42 public static final int SET_REPORTER_CODE = 3; 43 public static final int UNBIND_CODE = 4; 44 public static final int REBIND_CODE = 5; 45 public static final int GET_VALUE_CODE = 6; 46 public static final int SET_VALUE_CODE = 7; 47 public static final int GET_PID_CODE = 8; 48 public static final int GET_UID_CODE = 9; 49 public static final int GET_PPID_CODE = 10; 50 public static final int GET_ZYGOTE_PRELOAD_CALLED = 11; 51 52 public static Context sServiceContext = null; 53 54 private IBinder mReportObject; 55 private int mStartCount = 1; 56 private int mValue = 0; 57 58 private final IBinder mBinder = new Binder() { 59 @Override 60 protected boolean onTransact(int code, Parcel data, Parcel reply, 61 int flags) throws RemoteException { 62 switch (code) { 63 case SET_REPORTER_CODE: 64 data.enforceInterface(SERVICE_LOCAL); 65 mReportObject = data.readStrongBinder(); 66 return true; 67 case GET_VALUE_CODE: 68 data.enforceInterface(SERVICE_LOCAL); 69 reply.writeInt(mValue); 70 return true; 71 case SET_VALUE_CODE: 72 data.enforceInterface(SERVICE_LOCAL); 73 mValue = data.readInt(); 74 return true; 75 case GET_PID_CODE: 76 data.enforceInterface(SERVICE_LOCAL); 77 reply.writeInt(Process.myPid()); 78 return true; 79 case GET_UID_CODE: 80 data.enforceInterface(SERVICE_LOCAL); 81 reply.writeInt(Process.myUid()); 82 return true; 83 case GET_PPID_CODE: 84 data.enforceInterface(SERVICE_LOCAL); 85 reply.writeInt(Process.myPpid()); 86 return true; 87 case GET_ZYGOTE_PRELOAD_CALLED: 88 data.enforceInterface(SERVICE_LOCAL); 89 reply.writeBoolean(ZygotePreload.preloadCalled()); 90 return true; 91 default: 92 return super.onTransact(code, data, reply, flags); 93 } 94 } 95 }; 96 LocalService()97 public LocalService() { 98 } 99 100 @Override onStart(Intent intent, int startId)101 public void onStart(Intent intent, int startId) { 102 if (intent.getExtras() != null) { 103 IBinderParcelable parcelable 104 = (IBinderParcelable) intent.getExtras().getParcelable(REPORT_OBJ_NAME); 105 mReportObject = parcelable.binder; 106 if (mReportObject != null) { 107 bindAction(STARTED_CODE); 108 } 109 } 110 if (sServiceContext == null) { 111 sServiceContext = this; 112 } 113 } 114 115 @Override onDestroy()116 public void onDestroy() { 117 if (mReportObject != null) { 118 bindAction(DESTROYED_CODE); 119 } 120 } 121 122 @Override onBind(Intent intent)123 public IBinder onBind(Intent intent) { 124 if (sServiceContext == null) { 125 sServiceContext = this; 126 } 127 return mBinder; 128 } 129 130 @Override onUnbind(Intent intent)131 public boolean onUnbind(Intent intent) { 132 if (mReportObject != null) { 133 bindAction(UNBIND_CODE); 134 } 135 return true; 136 } 137 138 @Override onRebind(Intent intent)139 public void onRebind(Intent intent) { 140 if (mReportObject != null) { 141 bindAction(REBIND_CODE); 142 } 143 } 144 bindAction(final int bindCode)145 private void bindAction(final int bindCode) { 146 try { 147 Parcel data = Parcel.obtain(); 148 data.writeInterfaceToken(SERVICE_LOCAL); 149 if (bindCode == STARTED_CODE) { 150 data.writeInt(mStartCount); 151 mStartCount++; 152 } 153 mReportObject.transact( 154 bindCode, data, null, 0); 155 data.recycle(); 156 } catch (RemoteException e) { 157 // fail 158 } 159 } 160 } 161