Various update

This commit is contained in:
mar-v-in 2015-03-06 20:08:47 +01:00
parent 31d7aa58aa
commit 5227caab6c
16 changed files with 234 additions and 84 deletions

View File

@ -24,6 +24,11 @@
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="com.google.android.c2dm.permission.SEND"
android:protectionLevel="dangerous" />
<permission-tree android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
<permission
@ -48,6 +53,9 @@
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.SEND" />
<application
android:label="@string/gms_app_name"
android:icon="@drawable/ic_microg_app"

2
GmsApi

@ -1 +1 @@
Subproject commit adb160c25bf23be73738a732c94b903db41a338d
Subproject commit 4b5be5f4bb6b5e4e88a74011e8c150594769bcba

@ -1 +1 @@
Subproject commit a650ca5beac2a374460d820935b40f9539e692db
Subproject commit 462316b18e2620bd5c0cb843abd67671d941300d

@ -1 +1 @@
Subproject commit 1b2907207fd145efab7a1653d04134574a960a7d
Subproject commit 4ee1acc7385bc592506ac632d7a87c08372e345e

View File

@ -16,5 +16,18 @@
package com.google.android.gms.common.ui;
public class SignInButtonCreatorImpl {
import android.content.Context;
import android.view.View;
import com.google.android.gms.common.internal.ISignInButtonCreator;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
public class SignInButtonCreatorImpl extends ISignInButtonCreator.Stub {
@Override
public IObjectWrapper createSignInButton(IObjectWrapper contextWrapper, int size, int color) {
Context context = (Context) ObjectWrapper.unwrap(contextWrapper);
// TODO: real view :)
return ObjectWrapper.wrap(new View(context));
}
}

View File

@ -37,7 +37,7 @@ import android.widget.TextView;
import com.google.android.gms.R;
import org.microg.gms.common.Utils;
import org.microg.gms.common.PackageUtils;
import org.microg.gms.userinfo.ProfileManager;
import java.io.IOException;
@ -69,7 +69,7 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
service = getIntent().getStringExtra(AccountManager.KEY_AUTHTOKEN);
if (getIntent().hasExtra(EXTRA_FROM_ACCOUNT_MANAGER)) fromAccountManager = true;
int callerUid = getIntent().getIntExtra(AccountManager.KEY_CALLER_UID, 0);
Utils.checkPackage(this, packageName, callerUid);
PackageUtils.checkPackageUid(this, packageName, callerUid);
// receive package info
PackageManager packageManager = getPackageManager();
@ -135,7 +135,7 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
@Override
public void run() {
Context context = AskPermissionActivity.this;
String sig = Utils.getFirstPackageSignatureDigest(context, packageName);
String sig = PackageUtils.firstSignatureDigest(context, packageName);
AuthRequest request = new AuthRequest().fromContext(context)
.email(account.name)
.token(AccountManager.get(context).getPassword(account))

View File

@ -23,7 +23,7 @@ import android.content.pm.PackageManager;
import android.util.Log;
import org.microg.gms.common.Constants;
import org.microg.gms.common.Utils;
import org.microg.gms.common.PackageUtils;
public class AuthManager {
@ -91,7 +91,7 @@ public class AuthManager {
}
public static void storePermission(Context context, Account account, String packageName, String service) {
storePermission(context, account, packageName, Utils.getFirstPackageSignatureDigest(context, packageName), service);
storePermission(context, account, packageName, PackageUtils.firstSignatureDigest(context, packageName), service);
}
public static void storePermission(Context context, Account account, String packageName,

View File

@ -18,21 +18,17 @@ package org.microg.gms.auth;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.auth.IAuthManagerService;
import com.google.android.gms.auth.AccountChangeEventsRequest;
import com.google.android.gms.auth.AccountChangeEventsResponse;
import org.microg.gms.common.Utils;
import org.microg.gms.common.PackageUtils;
public class AuthManagerServiceImpl extends IAuthManagerService.Stub {
private static final String TAG = "GmsAuthManagerSvc";
@ -64,12 +60,12 @@ public class AuthManagerServiceImpl extends IAuthManagerService.Stub {
public Bundle getToken(String accountName, String scope, Bundle extras) throws RemoteException {
String packageName = extras.getString(KEY_ANDROID_PACKAGE_NAME, extras.getString(KEY_CLIENT_PACKAGE_NAME, null));
int callerUid = extras.getInt(KEY_CALLER_UID, 0);
Utils.checkPackage(context, packageName, callerUid, getCallingUid());
PackageUtils.checkPackageUid(context, packageName, callerUid, getCallingUid());
boolean notify = extras.getBoolean(KEY_HANDLE_NOTIFICATION, false);
Log.d(TAG, "getToken: account:" + accountName + " scope:" + scope + " extras:" + extras + ", notify: " + notify);
Account account = new Account(accountName, GOOGLE_ACCOUNT_TYPE);
String sig = Utils.getFirstPackageSignatureDigest(context, packageName);
String sig = PackageUtils.firstSignatureDigest(context, packageName);
if (!AuthManager.isPermitted(context, account, packageName, sig, scope)) {
Bundle result = new Bundle();

View File

@ -34,7 +34,7 @@ import org.microg.gms.auth.AuthManager;
import org.microg.gms.auth.AuthRequest;
import org.microg.gms.auth.AuthResponse;
import org.microg.gms.auth.login.LoginActivity;
import org.microg.gms.common.Utils;
import org.microg.gms.common.PackageUtils;
import java.io.IOException;
import java.util.Arrays;
@ -106,8 +106,8 @@ public class GoogleLoginService extends Service {
options.keySet();
Log.d(TAG, "getAuthToken: " + account + ", " + authTokenType + ", " + options);
String app = options.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
Utils.checkPackage(this, app, options.getInt(AccountManager.KEY_CALLER_UID), options.getInt(AccountManager.KEY_CALLER_UID));
String appSignature = Utils.getFirstPackageSignatureDigest(this, app);
PackageUtils.checkPackageUid(this, app, options.getInt(AccountManager.KEY_CALLER_UID), options.getInt(AccountManager.KEY_CALLER_UID));
String appSignature = PackageUtils.firstSignatureDigest(this, app);
if (!AuthManager.isPermitted(this, account, app, appSignature, authTokenType)) {
Bundle result = new Bundle();
Intent i = new Intent(this, AskPermissionActivity.class);

View File

@ -0,0 +1,89 @@
/*
* Copyright 2013-2015 µg Project Team
*
* 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 org.microg.gms.common;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class PackageUtils {
public static void checkPackageUid(Context context, String packageName, int callingUid) {
String[] packagesForUid = context.getPackageManager().getPackagesForUid(callingUid);
if (packagesForUid != null && !Arrays.asList(packagesForUid).contains(packageName)) {
throw new SecurityException("callingUid [" + callingUid + "] is not related to packageName [" + packageName + "]");
}
}
public static void checkPackageUid(Context context, String packageName, int callerUid, int callingUid) {
if (callerUid != 0 && callerUid != callingUid) {
throw new SecurityException("callerUid [" + callerUid + "] and real calling uid [" + callingUid + "] mismatch!");
}
checkPackageUid(context, packageName, callingUid);
}
public static String firstSignatureDigest(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();
final PackageInfo info;
try {
info = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
if (info != null && info.signatures != null && info.signatures.length > 0) {
for (Signature sig : info.signatures) {
String digest = sha1sum(sig.toByteArray());
if (digest != null) {
return digest;
}
}
}
return null;
}
public static String sha1sum(byte[] bytes) {
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA1");
} catch (final NoSuchAlgorithmException e) {
return null;
}
if (md != null) {
bytes = md.digest(bytes);
if (bytes != null) {
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
return null;
}
public static int versionCode(Context context, String packageName) {
try {
return context.getPackageManager().getPackageInfo(packageName, 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -21,6 +21,8 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import org.microg.gms.checkin.LastCheckinInfo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@ -31,7 +33,7 @@ import java.util.Locale;
public class Utils {
public static String getAndroidIdHex(Context context) {
return null;
return Long.toHexString(LastCheckinInfo.read(context).androidId);
}
public static Locale getLocale(Context context) {
@ -42,59 +44,6 @@ public class Utils {
return new Build();
}
public static void checkPackage(Context context, String packageName, int callingUid) {
String[] packagesForUid = context.getPackageManager().getPackagesForUid(callingUid);
if (packagesForUid != null && !Arrays.asList(packagesForUid).contains(packageName)) {
throw new SecurityException("callingUid [" + callingUid + "] is not related to packageName [" + packageName + "]");
}
}
public static void checkPackage(Context context, String packageName, int callerUid, int callingUid) {
if (callerUid != 0 && callerUid != callingUid) {
throw new SecurityException("callerUid [" + callerUid + "] and real calling uid [" + callingUid + "] mismatch!");
}
checkPackage(context, packageName, callingUid);
}
public static String getFirstPackageSignatureDigest(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();
final PackageInfo info;
try {
info = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(e);
}
if (info != null && info.signatures != null && info.signatures.length > 0) {
for (Signature sig : info.signatures) {
String digest = sha1sum(sig.toByteArray());
if (digest != null) {
return digest;
}
}
}
return null;
}
public static String sha1sum(byte[] bytes) {
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA1");
} catch (final NoSuchAlgorithmException e) {
return null;
}
if (md != null) {
bytes = md.digest(bytes);
if (bytes != null) {
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
return null;
}
public static byte[] readStreamToEnd(final InputStream is) throws IOException {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (is != null) {

View File

@ -17,16 +17,31 @@
package org.microg.gms.gcm;
import android.content.Context;
import android.util.Log;
import org.microg.gms.checkin.LastCheckinInfo;
import org.microg.gms.common.PackageUtils;
import org.microg.gms.common.Utils;
import java.io.IOException;
public class GcmManager {
private static final String TAG = "GmsGcmManager";
public static String register(Context context, String app, String sender, String info) {
new RegisterRequest()
.build(Utils.getBuild(context))
.sender(sender)
.info(info)
.app(app, Utils.getFirstPackageSignatureDigest(context, app), 0); // TODO
try {
return new RegisterRequest()
.build(Utils.getBuild(context))
.sender(sender)
.info(info)
.checkin(LastCheckinInfo.read(context))
.app(app, PackageUtils.firstSignatureDigest(context, app), PackageUtils.versionCode(context, app))
.getResponse()
.token;
} catch (IOException e) {
Log.w(TAG, e);
}
return null;
}
}

View File

@ -20,6 +20,7 @@ import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
public class PushRegisterService extends IntentService {
@ -58,14 +59,18 @@ public class PushRegisterService extends IntentService {
PendingIntent pendingIntent = intent.getParcelableExtra("app");
String sender = intent.getStringExtra("sender");
String app = packageFromPendingIntent(pendingIntent);
Bundle extras = intent.getExtras();
extras.keySet();
Log.d(TAG, "register[req]: " + extras);
Intent outIntent = new Intent("com.google.android.c2dm.intent.REGISTRATION");
outIntent.setPackage(app);
String regId = GcmManager.register(this, app, sender, null); // TODO
String regId = GcmManager.register(this, app, sender, null);
if (regId != null) {
outIntent.putExtra("registration_id", regId);
} else {
outIntent.putExtra("error", "SERVICE_NOT_AVAILABLE");
}
Log.d(TAG, "register[res]: " + outIntent);
sendOrderedBroadcast(outIntent, null);
}

View File

@ -28,9 +28,10 @@ import java.util.Map;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 3;
private static final int DB_VERSION_OLD = 1;
public static final String DB_NAME = "gservices.db";
public DatabaseHelper(Context context) {
super(context, "gservices.db", null, DB_VERSION);
super(context, DB_NAME, null, DB_VERSION);
}
@Override

View File

@ -0,0 +1,72 @@
/*
* Copyright 2013-2015 µg Project Team
*
* 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 org.microg.gms.people;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DB_VERSION = 1;
private static final String DB_NAME = "pluscontacts.db";
private static final String CREATE_OWNERS = "CREATE TABLE owners (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"account_name TEXT NOT NULL UNIQUE," +
"gaia_id TEXT," +
"page_gaia_id TEXT," +
"display_name TEXT," +
"avatar TEXT," +
"cover_photo_url TEXT," +
"cover_photo_height INTEGER NOT NULL DEFAULT 0," +
"cover_photo_width INTEGER NOT NULL DEFAULT 0," +
"cover_photo_id TEXT," +
"last_sync_start_time INTEGER NOT NULL DEFAULT 0," +
"last_sync_finish_time INTEGER NOT NULL DEFAULT 0," +
"last_sync_status INTEGER NOT NULL DEFAULT 0," +
"last_successful_sync_time INTEGER NOT NULL DEFAULT 0," +
"sync_to_contacts INTEGER NOT NULL DEFAULT 0," +
"is_dasher INTEGER NOT NULL DEFAULT 0," +
"dasher_domain TEXT," +
"etag TEXT," +
"sync_circles_to_contacts INTEGER NOT NULL DEFAULT 0," +
"sync_evergreen_to_contacts INTEGER NOT NULL DEFAULT 0," +
"last_full_people_sync_time INTEGER NOT NULL DEFAULT 0);";
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_OWNERS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// silently accept
}
public Cursor getOwners() {
return getReadableDatabase().query("owners", null, null, null, null, null, null);
}
}

View File

@ -27,7 +27,6 @@ import android.util.Log;
import com.google.android.gms.common.data.DataHolder;
import com.google.android.gms.people.internal.IPeopleCallbacks;
import com.google.android.gms.people.internal.IPeopleService;
import com.google.android.gms.people.model.AccountMetadata;
public class PeopleServiceImpl extends IPeopleService.Stub {
private static final String TAG = "GmsPeopleSvcImpl";
@ -47,12 +46,15 @@ public class PeopleServiceImpl extends IPeopleService.Stub {
Bundle result = new Bundle();
for (Account account : accountManager.getAccountsByType("com.google")) {
if (accountName == null || account.name.equals(accountName)) {
result.putParcelable(account.name, new AccountMetadata());
result.putParcelable(account.name, null);
}
}
try {
callbacks.onDataHolders(0, result, new DataHolder[0]);
} catch (RemoteException e) {
DatabaseHelper databaseHelper = new DatabaseHelper(context);
DataHolder dataHolder = DataHolder.fromCursor(databaseHelper.getOwners(), 0, result);
Log.d(TAG, "loadOwners[result]: " + dataHolder);
callbacks.onDataHolder(0, result, dataHolder);
} catch (Exception e) {
Log.w(TAG, e);
}
}