239 lines
9.3 KiB
Java
239 lines
9.3 KiB
Java
/*
|
|
* Twidere - Twitter client for Android
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you 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.mariotaku.twidere;
|
|
|
|
import android.Manifest;
|
|
import android.accounts.Account;
|
|
import android.accounts.AccountManager;
|
|
import android.app.Activity;
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.ApplicationInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.database.Cursor;
|
|
import android.graphics.Color;
|
|
import android.os.Bundle;
|
|
import android.support.annotation.IntDef;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.annotation.Nullable;
|
|
import android.support.annotation.RequiresPermission;
|
|
|
|
import org.mariotaku.twidere.model.AccountDetails;
|
|
import org.mariotaku.twidere.model.ComposingStatus;
|
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
|
import org.mariotaku.twidere.model.ParcelableUser;
|
|
import org.mariotaku.twidere.model.ParcelableUserList;
|
|
import org.mariotaku.twidere.model.UserKey;
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.Permissions;
|
|
import org.mariotaku.twidere.util.JsonSerializer;
|
|
import org.mariotaku.twidere.util.model.AccountDetailsUtils;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.net.Inet4Address;
|
|
import java.net.Inet6Address;
|
|
import java.net.InetAddress;
|
|
import java.net.UnknownHostException;
|
|
|
|
import static android.text.TextUtils.isEmpty;
|
|
|
|
@SuppressWarnings("unused")
|
|
public final class Twidere implements TwidereConstants {
|
|
|
|
public static void appendComposeActivityText(final Activity activity, final String text) {
|
|
if (activity == null) return;
|
|
final Intent intent = new Intent();
|
|
final Bundle extras = new Bundle();
|
|
extras.putString(EXTRA_APPEND_TEXT, text);
|
|
intent.putExtras(extras);
|
|
activity.setResult(Activity.RESULT_OK, intent);
|
|
activity.finish();
|
|
}
|
|
|
|
public static ComposingStatus getComposingStatusFromIntent(final Intent intent) {
|
|
if (intent == null) return null;
|
|
return new ComposingStatus(intent);
|
|
}
|
|
|
|
public static ParcelableStatus getStatusFromIntent(final Intent intent) {
|
|
if (intent == null) return null;
|
|
return intent.getParcelableExtra(EXTRA_STATUS);
|
|
}
|
|
|
|
public static ParcelableUser getUserFromIntent(final Intent intent) {
|
|
if (intent == null) return null;
|
|
return intent.getParcelableExtra(EXTRA_USER);
|
|
}
|
|
|
|
public static ParcelableUserList getUserListFromIntent(final Intent intent) {
|
|
if (intent == null) return null;
|
|
return intent.getParcelableExtra(EXTRA_USER_LIST);
|
|
}
|
|
|
|
@Permission
|
|
public static int isPermissionGranted(final Context context) {
|
|
final PackageManager pm = context.getPackageManager();
|
|
final String pname = context.getPackageName();
|
|
final ApplicationInfo info;
|
|
try {
|
|
info = pm.getPackageInfo(pname, PackageManager.GET_META_DATA).applicationInfo;
|
|
} catch (final PackageManager.NameNotFoundException e) {
|
|
return Permission.NONE;
|
|
}
|
|
if (info.metaData == null) return Permission.NONE;
|
|
final String[] required = parsePermissions(info.metaData.getString(METADATA_KEY_EXTENSION_PERMISSIONS));
|
|
final String[] permissions = getPermissions(context, pname);
|
|
return checkPermissionRequirement(required, permissions);
|
|
}
|
|
|
|
public static int checkPermissionRequirement(@NonNull String[] required, @NonNull String[] permissions) {
|
|
if (indexOf(permissions, PERMISSION_DENIED) != -1) {
|
|
return Permission.DENIED;
|
|
} else {
|
|
for (String s : required) {
|
|
if (indexOf(permissions, s) == -1) return Permission.NONE;
|
|
}
|
|
return Permission.GRANTED;
|
|
}
|
|
}
|
|
|
|
@NonNull
|
|
public static String[] getPermissions(Context context, String pname) {
|
|
final ContentResolver resolver = context.getContentResolver();
|
|
final Cursor c = resolver.query(Permissions.CONTENT_URI, null, null, null, null);
|
|
if (c == null) return new String[0];
|
|
try {
|
|
c.moveToFirst();
|
|
final int idxPackageName = c.getColumnIndex(Permissions.PACKAGE_NAME), idxPermissions = c
|
|
.getColumnIndex(Permissions.PERMISSION);
|
|
while (!c.isAfterLast()) {
|
|
if (pname.equals(c.getString(idxPackageName))) {
|
|
return parsePermissions(c.getString(idxPermissions));
|
|
}
|
|
c.moveToNext();
|
|
}
|
|
} catch (final SecurityException ignore) {
|
|
|
|
} finally {
|
|
c.close();
|
|
}
|
|
return new String[0];
|
|
}
|
|
|
|
@NonNull
|
|
public static String[] parsePermissions(final String permissionsString) {
|
|
if (isEmpty(permissionsString)) return new String[0];
|
|
return permissionsString.split(SEPARATOR_PERMISSION_REGEX);
|
|
}
|
|
|
|
public static void replaceComposeActivityText(final Activity activity, final String text) {
|
|
if (activity == null) return;
|
|
final Intent intent = new Intent();
|
|
intent.putExtra(EXTRA_TEXT, text);
|
|
activity.setResult(Activity.RESULT_OK, intent);
|
|
activity.finish();
|
|
}
|
|
|
|
private static InetAddress fromAddressString(String host, String address) throws UnknownHostException {
|
|
InetAddress inetAddress = InetAddress.getByName(address);
|
|
if (inetAddress instanceof Inet4Address) {
|
|
return Inet4Address.getByAddress(host, inetAddress.getAddress());
|
|
} else if (inetAddress instanceof Inet6Address) {
|
|
return Inet6Address.getByAddress(host, inetAddress.getAddress());
|
|
}
|
|
throw new UnknownHostException("Bad address " + host + " = " + address);
|
|
}
|
|
|
|
@Nullable
|
|
@RequiresPermission(allOf = {Manifest.permission.GET_ACCOUNTS}, conditional = true)
|
|
public static Account findByAccountKey(@NonNull Context context, @NonNull UserKey userKey) {
|
|
final AccountManager am = AccountManager.get(context);
|
|
for (Account account : am.getAccountsByType(ACCOUNT_TYPE)) {
|
|
if (userKey.equals(getAccountKey(account, am))) {
|
|
return account;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@RequiresPermission(allOf = {"android.permission.AUTHENTICATE_ACCOUNTS"}, conditional = true)
|
|
@NonNull
|
|
public static AccountDetails getAccountDetails(Context context, Account account) throws SecurityException {
|
|
final AccountManager am = AccountManager.get(context);
|
|
final AccountDetails details = new AccountDetails();
|
|
details.account = account;
|
|
details.key = getAccountKey(account, am);
|
|
//noinspection WrongConstant
|
|
details.type = am.getUserData(account, ACCOUNT_USER_DATA_TYPE);
|
|
details.color = Color.parseColor(am.getUserData(account, ACCOUNT_USER_DATA_COLOR));
|
|
details.position = Integer.parseInt(am.getUserData(account, ACCOUNT_USER_DATA_POSITION));
|
|
//noinspection WrongConstant
|
|
details.credentials_type = am.getUserData(account, ACCOUNT_USER_DATA_CREDS_TYPE);
|
|
try {
|
|
details.user = JsonSerializer.parse(am.getUserData(account, ACCOUNT_USER_DATA_USER),
|
|
ParcelableUser.class);
|
|
} catch (IOException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
details.activated = Boolean.parseBoolean(am.getUserData(account, ACCOUNT_USER_DATA_ACTIVATED));
|
|
|
|
try {
|
|
details.credentials = AccountDetailsUtils.parseCredentials(am.peekAuthToken(account, ACCOUNT_AUTH_TOKEN_TYPE),
|
|
details.credentials_type);
|
|
} catch (SecurityException e) {
|
|
// Ignore
|
|
}
|
|
details.extras = AccountDetailsUtils.parseAccountExtras(am.getUserData(account, ACCOUNT_USER_DATA_EXTRAS), details.type);
|
|
|
|
details.user.color = details.color;
|
|
|
|
return details;
|
|
}
|
|
|
|
@NonNull
|
|
@RequiresPermission(allOf = {"android.permission.AUTHENTICATE_ACCOUNTS"}, conditional = true)
|
|
private static UserKey getAccountKey(Account account, AccountManager am) {
|
|
return UserKey.valueOf(am.getUserData(account, ACCOUNT_USER_DATA_KEY));
|
|
}
|
|
|
|
private static int indexOf(String[] input, String find) {
|
|
for (int i = 0, inputLength = input.length; i < inputLength; i++) {
|
|
if (find == null) {
|
|
if (input[i] == null) return i;
|
|
} else if (find.equals(input[i])) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
@IntDef({Permission.DENIED, Permission.NONE, Permission.GRANTED})
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
public @interface Permission {
|
|
int NONE = 0;
|
|
int GRANTED = 1;
|
|
int DENIED = -1;
|
|
}
|
|
|
|
|
|
}
|