• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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