/**
* Copyright 2010-present Facebook.
*
* 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.facebook.internal;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.*;
/**
* com.facebook.internal is solely for the use of other packages within the Facebook SDK for Android. Use of
* any of the classes in this package is unsupported, and they may be modified or removed without warning at
* any time.
*/
abstract public class PlatformServiceClient implements ServiceConnection {
private final Context context;
private final Handler handler;
private CompletedListener listener;
private boolean running;
private Messenger sender;
private int requestMessage;
private int replyMessage;
private final String applicationId;
private final int protocolVersion;
public PlatformServiceClient(Context context, int requestMessage, int replyMessage, int protocolVersion,
String applicationId) {
Context applicationContext = context.getApplicationContext();
this.context = (applicationContext != null) ? applicationContext : context;
this.requestMessage = requestMessage;
this.replyMessage = replyMessage;
this.applicationId = applicationId;
this.protocolVersion = protocolVersion;
handler = new Handler() {
@Override
public void handleMessage(Message message) {
PlatformServiceClient.this.handleMessage(message);
}
};
}
public void setCompletedListener(CompletedListener listener) {
this.listener = listener;
}
protected Context getContext() {
return context;
}
public boolean start() {
if (running) {
return false;
}
// Make sure that the service can handle the requested protocol version
int availableVersion = NativeProtocol.getLatestAvailableProtocolVersionForService(context, protocolVersion);
if (availableVersion == NativeProtocol.NO_PROTOCOL_AVAILABLE) {
return false;
}
Intent intent = NativeProtocol.createPlatformServiceIntent(context);
if (intent == null) {
return false;
} else {
running = true;
context.bindService(intent, this, Context.BIND_AUTO_CREATE);
return true;
}
}
public void cancel() {
running = false;
}
public void onServiceConnected(ComponentName name, IBinder service) {
sender = new Messenger(service);
sendMessage();
}
public void onServiceDisconnected(ComponentName name) {
sender = null;
try {
context.unbindService(this);
} catch (IllegalArgumentException ex) {
// Do nothing, the connection was already unbound
}
callback(null);
}
private void sendMessage() {
Bundle data = new Bundle();
data.putString(NativeProtocol.EXTRA_APPLICATION_ID, applicationId);
populateRequestBundle(data);
Message request = Message.obtain(null, requestMessage);
request.arg1 = protocolVersion;
request.setData(data);
request.replyTo = new Messenger(handler);
try {
sender.send(request);
} catch (RemoteException e) {
callback(null);
}
}
protected abstract void populateRequestBundle(Bundle data);
protected void handleMessage(Message message) {
if (message.what == replyMessage) {
Bundle extras = message.getData();
String errorType = extras.getString(NativeProtocol.STATUS_ERROR_TYPE);
if (errorType != null) {
callback(null);
} else {
callback(extras);
}
context.unbindService(this);
}
}
private void callback(Bundle result) {
if (!running) {
return;
}
running = false;
CompletedListener callback = listener;
if (callback != null) {
callback.completed(result);
}
}
public interface CompletedListener {
void completed(Bundle result);
}
}