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 public static final int STOP_SELF_CODE = 12; 52 public static final int STOP_SELF_RESULT_CODE = 13; 53 public static final int STOP_SELF_SUCCESS_UNBIND_CODE = 14; 54 55 public static Context sServiceContext = null; 56 57 private IBinder mReportObject; 58 private int mStartCount = 1; 59 private int mValue = 0; 60 private int mStartId = -1; 61 private boolean mIsStoppedSelfSuccess; 62 63 private final IBinder mBinder = new Binder() { 64 @Override 65 protected boolean onTransact(int code, Parcel data, Parcel reply, 66 int flags) throws RemoteException { 67 switch (code) { 68 case SET_REPORTER_CODE: 69 data.enforceInterface(SERVICE_LOCAL); 70 mReportObject = data.readStrongBinder(); 71 return true; 72 case GET_VALUE_CODE: 73 data.enforceInterface(SERVICE_LOCAL); 74 reply.writeInt(mValue); 75 return true; 76 case SET_VALUE_CODE: 77 data.enforceInterface(SERVICE_LOCAL); 78 mValue = data.readInt(); 79 return true; 80 case GET_PID_CODE: 81 data.enforceInterface(SERVICE_LOCAL); 82 reply.writeInt(Process.myPid()); 83 return true; 84 case GET_UID_CODE: 85 data.enforceInterface(SERVICE_LOCAL); 86 reply.writeInt(Process.myUid()); 87 return true; 88 case GET_PPID_CODE: 89 data.enforceInterface(SERVICE_LOCAL); 90 reply.writeInt(Process.myPpid()); 91 return true; 92 case GET_ZYGOTE_PRELOAD_CALLED: 93 data.enforceInterface(SERVICE_LOCAL); 94 reply.writeBoolean(ZygotePreload.preloadCalled()); 95 return true; 96 case STOP_SELF_RESULT_CODE: 97 mIsStoppedSelfSuccess = stopSelfResult(mStartId); 98 return true; 99 case STOP_SELF_CODE: 100 stopSelf(mStartId); 101 return true; 102 default: 103 return super.onTransact(code, data, reply, flags); 104 } 105 } 106 }; 107 LocalService()108 public LocalService() { 109 } 110 111 @Override onStart(Intent intent, int startId)112 public void onStart(Intent intent, int startId) { 113 mStartId = startId; 114 if (intent.getExtras() != null) { 115 IBinderParcelable parcelable 116 = (IBinderParcelable) intent.getExtras().getParcelable(REPORT_OBJ_NAME); 117 mReportObject = parcelable.binder; 118 if (mReportObject != null) { 119 bindAction(STARTED_CODE); 120 } 121 } 122 if (sServiceContext == null) { 123 sServiceContext = this; 124 } 125 } 126 127 @Override onDestroy()128 public void onDestroy() { 129 if (mReportObject != null) { 130 bindAction(DESTROYED_CODE); 131 } 132 } 133 134 @Override onBind(Intent intent)135 public IBinder onBind(Intent intent) { 136 if (sServiceContext == null) { 137 sServiceContext = this; 138 } 139 return mBinder; 140 } 141 142 @Override onUnbind(Intent intent)143 public boolean onUnbind(Intent intent) { 144 if (mReportObject != null) { 145 if (mIsStoppedSelfSuccess) { 146 bindAction(STOP_SELF_SUCCESS_UNBIND_CODE); 147 } else { 148 bindAction(UNBIND_CODE); 149 } 150 } 151 return true; 152 } 153 154 @Override onRebind(Intent intent)155 public void onRebind(Intent intent) { 156 if (mReportObject != null) { 157 bindAction(REBIND_CODE); 158 } 159 } 160 bindAction(final int bindCode)161 private void bindAction(final int bindCode) { 162 try { 163 Parcel data = Parcel.obtain(); 164 data.writeInterfaceToken(SERVICE_LOCAL); 165 if (bindCode == STARTED_CODE) { 166 data.writeInt(mStartCount); 167 mStartCount++; 168 } 169 mReportObject.transact( 170 bindCode, data, null, 0); 171 data.recycle(); 172 } catch (RemoteException e) { 173 // fail 174 } 175 } 176 } 177