blob: 4e981b22cd3200a6d2b43e5b8842e59674b49496 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.servicestests.apps.simpleservicetestapp;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Process;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
public class SimpleService extends Service {
private static final String TAG = "SimpleService";
private static final String TEST_CLASS =
"com.android.servicestests.apps.simpleservicetestapp.SimpleService";
private static final String EXTRA_CALLBACK = "callback";
private static final String EXTRA_COMMAND = "command";
private static final String EXTRA_FLAGS = "flags";
private static final String EXTRA_TARGET_PACKAGE = "target_package";
private static final int COMMAND_INVALID = 0;
private static final int COMMAND_EMPTY = 1;
private static final int COMMAND_BIND_SERVICE = 2;
private static final int COMMAND_UNBIND_SERVICE = 3;
private static final int COMMAND_STOP_SELF = 4;
private ArrayMap<String, ServiceConnection> mServiceConnections = new ArrayMap<>();
private final IRemoteCallback.Stub mBinder = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle bundle) {
if (bundle == null) {
Process.killProcess(Process.myPid());
} else {
// No-op for now.
}
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
int command = intent.getIntExtra(EXTRA_COMMAND, COMMAND_INVALID);
if (command != COMMAND_INVALID) {
final String targetPkg = intent.getStringExtra(EXTRA_TARGET_PACKAGE);
Log.i(TAG, "Received command " + command + " targetPkg=" + targetPkg);
switch (command) {
case COMMAND_BIND_SERVICE:
final Bundle extras = intent.getExtras();
bindToService(targetPkg, intent.getIntExtra(EXTRA_FLAGS, 0),
IRemoteCallback.Stub.asInterface(extras.getBinder(EXTRA_CALLBACK)));
break;
case COMMAND_UNBIND_SERVICE:
unbindService(targetPkg);
break;
case COMMAND_STOP_SELF:
stopSelf();
return START_NOT_STICKY;
}
}
return START_STICKY;
}
private void bindToService(String targetPkg, int flags, IRemoteCallback callback) {
Intent intent = new Intent();
intent.setClassName(targetPkg, TEST_CLASS);
final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (callback != null) {
try {
callback.sendResult(new Bundle());
} catch (RemoteException e) {
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
if (getApplicationContext().bindService(intent, conn, BIND_AUTO_CREATE | flags)) {
mServiceConnections.put(targetPkg, conn);
} else if (callback != null) {
try {
callback.sendResult(null);
} catch (RemoteException e) {
}
}
}
private void unbindService(String targetPkg) {
final ServiceConnection conn = mServiceConnections.remove(targetPkg);
if (conn != null) {
getApplicationContext().unbindService(conn);
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}