// ISystemInterface.aidl
package com.wq.binderexample;
// Declare any non-default types here with import statements
interface ISystemInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
//void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
// double aDouble, String aString);
String getWiFiSSID();
}
public class SystemService extends Service {
private final String TAG = SystemService.class.getSimpleName();
private final String[] PermittedSignatures = {
"4LgyWU9gZ03bvH14X004K5fsVKqsJQAOj2lWmG5Fu64=",
};
private final ISystemInterface.Stub mInterface = new ISystemInterface.Stub() {
@Override
public String getWiFiSSID() throws SecurityException {
if (checkPermission()) {
return "hello";
} else {
throw new SecurityException("No Permission");
}
}
};
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return mInterface;
}
}
boolean checkPermission() {
String callingApp = getBaseContext().getPackageManager().getNameForUid(Binder.getCallingUid());
Log.i(TAG, "calling app: " + callingApp);
try {
Signature[] sis = getApplicationSignature(callingApp);
final MessageDigest md = MessageDigest.getInstance("SHA256");
for (Signature si : sis) {
md.update(si.toByteArray());
final String siBase64 = new String(Base64.encode(md.digest(), Base64.DEFAULT));
Log.i(TAG,"Signature Base64: " + siBase64);
for (String permittedSignature : PermittedSignatures) {
Log.i(TAG, "permittedSignature: " + permittedSignature);
if (permittedSignature.equals(siBase64.trim())) {
return true;
}
}
}
} catch (java.security.NoSuchAlgorithmException e) {
Log.e(TAG, "No MessageDigest Algorithm", e);
return false;
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Can not find specific information", e);
return false;
}
return false;
}
private Signature[] getApplicationSignature(String packageName) throws PackageManager.NameNotFoundException {
Signature[] sig;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
sig = getSignatureBySigningInfo(packageName);
} else {
sig = getRawSignature(packageName);
}
return sig;
}
private Signature[] getRawSignature(String packageName) throws PackageManager.NameNotFoundException {
if ((packageName == null) || (packageName.length() == 0)) {
Log.e(TAG, "package name is error!");
return null;
}
PackageManager pm = getBaseContext().getPackageManager();
PackageInfo pi;
pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
if (pi == null) {
Log.e(TAG, "Can not get package info, package name is: " + packageName);
return null;
}
return pi.signatures;
}
private Signature[] getSignatureBySigningInfo(String packageName) throws PackageManager.NameNotFoundException {
if ((packageName == null) || (packageName.length() == 0)) {
Log.e(TAG, "package name is error!");
return null;
}
PackageManager pm = getBaseContext().getPackageManager();
PackageInfo pi;
pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES);
if (pi == null) {
Log.e(TAG, "Can not get package info, package name is: " + packageName);
return null;
}
return pi.signingInfo.getApkContentsSigners();
}
public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
/* protected by mLock */
private final Object mLock = new Object();
private static ISystemInterface mInterface;
private Context mContext = App.getContext();
private Button mButton;
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i(TAG, "System service has been connected!");
synchronized (mLock) {
mInterface = ISystemInterface.Stub.asInterface(iBinder);
mLock.notify();
}
try {
String ssid = mInterface.getWiFiSSID();
Log.i(TAG, "ssid = " + ssid);
} catch (RemoteException e) {
Log.e(TAG, "call interface error!", e);
} catch (SecurityException e) {
Log.e(TAG, "Can not call remote interface", e);
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
synchronized (mLock) {
mInterface = null;
}
Log.i(TAG, "System service has exited!");
//rebind service
Intent intent = new Intent(mContext, SystemService.class);
mContext.bindService(intent, mConn, mContext.BIND_AUTO_CREATE);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.mButton);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(TAG, "Button click");
// binder service
synchronized (mLock) {
if (mInterface == null) {
//bind service
Log.i(TAG, "bind SystemService");
Intent intent = new Intent(mContext, SystemService.class);
mContext.bindService(intent, mConn, mContext.BIND_AUTO_CREATE);
}
}
}
});
}
}