android.content.SyncAdapterType Java Examples

The following examples show how to use android.content.SyncAdapterType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 7 votes vote down vote up
static void sendOnUnsyncableAccount(@NonNull Context context,
        @NonNull RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo,
        @UserIdInt int userId, @NonNull OnReadyCallback onReadyCallback) {
    OnUnsyncableAccountCheck connection = new OnUnsyncableAccountCheck(syncAdapterInfo,
            onReadyCallback);

    boolean isBound = context.bindServiceAsUser(
            getAdapterBindIntent(context, syncAdapterInfo.componentName, userId),
            connection, SYNC_ADAPTER_CONNECTION_FLAGS, UserHandle.of(userId));

    if (isBound) {
        // Unbind after SERVICE_BOUND_TIME_MILLIS to not leak the connection.
        (new Handler(Looper.getMainLooper())).postDelayed(
                () -> context.unbindService(connection),
                OnUnsyncableAccountCheck.SERVICE_BOUND_TIME_MILLIS);
    } else {
            /*
             * The default implementation of adapter.onUnsyncableAccount returns true. Hence if
             * there the service cannot be bound, assume the default behavior.
             */
        connection.onReady();
    }
}
 
Example #2
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
private void whiteListExistingSyncAdaptersIfNeeded() {
    if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) {
        return;
    }
    List<UserInfo> users = mUserManager.getUsers(true);
    final int userCount = users.size();
    for (int i = 0; i < userCount; i++) {
        UserHandle userHandle = users.get(i).getUserHandle();
        final int userId = userHandle.getIdentifier();
        for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> service
                : mSyncAdapters.getAllServices(userId)) {
            String packageName = service.componentName.getPackageName();
            for (Account account : mAccountManager.getAccountsByTypeAsUser(
                    service.type.accountType, userHandle)) {
                if (!canAccessAccount(account, packageName, userId)) {
                    mAccountManager.updateAppPermission(account,
                            AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE, service.uid, true);
                }
            }
        }
    }
}
 
Example #3
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 6 votes vote down vote up
private int getIsSyncable(Account account, int userId, String providerName) {
    int isSyncable = mSyncStorageEngine.getIsSyncable(account, userId, providerName);
    UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId);

    // If it's not a restricted user, return isSyncable.
    if (userInfo == null || !userInfo.isRestricted()) return isSyncable;

    // Else check if the sync adapter has opted-in or not.
    RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
            mSyncAdapters.getServiceInfo(
                    SyncAdapterType.newKey(providerName, account.type), userId);
    if (syncAdapterInfo == null) return AuthorityInfo.NOT_SYNCABLE;

    PackageInfo pInfo = null;
    try {
        pInfo = AppGlobals.getPackageManager().getPackageInfo(
                syncAdapterInfo.componentName.getPackageName(), 0, userId);
        if (pInfo == null) return AuthorityInfo.NOT_SYNCABLE;
    } catch (RemoteException re) {
        // Shouldn't happen.
        return AuthorityInfo.NOT_SYNCABLE;
    }
    if (pInfo.restrictedAccountType != null
            && pInfo.restrictedAccountType.equals(account.type)) {
        return isSyncable;
    } else {
        return AuthorityInfo.NOT_SYNCABLE;
    }
}
 
Example #4
Source File: ContentService.java    From AndroidComponentPlugin with Apache License 2.0 5 votes vote down vote up
/**
 * Get information about the SyncAdapters that are known to the system for a particular user.
 *
 * <p> If the user id supplied is different to the calling user, the caller must hold the
 * INTERACT_ACROSS_USERS_FULL permission.
 *
 * @return an array of SyncAdapters that have registered with the system
 */
@Override
public SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
    enforceCrossUserPermission(userId,
            "no permission to read sync settings for user " + userId);
    // This makes it so that future permission checks will be in the context of this
    // process rather than the caller's process. We will restore this before returning.
    final long identityToken = clearCallingIdentity();
    try {
        SyncManager syncManager = getSyncManager();
        return syncManager.getSyncAdapterTypes(userId);
    } finally {
        restoreCallingIdentity(identityToken);
    }
}
 
Example #5
Source File: AccountSnippet.java    From mobly-bundled-snippets with Apache License 2.0 5 votes vote down vote up
/**
 * Disables syncing of a SyncAdapter for a given content provider.
 *
 * <p>Removes the content provider authority from a whitelist.
 *
 * @param username Username of the account (including @gmail.com).
 * @param authority The authority of a content provider that should not be synced.
 */
@Rpc(description = "Disables syncing of a SyncAdapter for a content provider.")
public void stopSync(String username, String authority) throws AccountSnippetException {
    if (!listAccounts().contains(username)) {
        throw new AccountSnippetException("Account " + username + " is not on the device");
    }
    // Remove from whitelist
    mLock.writeLock().lock();
    try {
        if (mSyncWhitelist.containsKey(username)) {
            Set<String> whitelistedProviders = mSyncWhitelist.get(username);
            whitelistedProviders.remove(authority);
            if (whitelistedProviders.isEmpty()) {
                mSyncWhitelist.remove(username);
            }
        }
        // Update the Sync settings
        for (SyncAdapterType adapter : ContentResolver.getSyncAdapterTypes()) {
            // Find the Google account content provider.
            if (adapter.accountType.equals(GOOGLE_ACCOUNT_TYPE)
                    && adapter.authority.equals(authority)) {
                Account account = new Account(username, GOOGLE_ACCOUNT_TYPE);
                updateSync(account, authority, false);
            }
        }
    } finally {
        mLock.writeLock().unlock();
    }
}
 
Example #6
Source File: AccountSnippet.java    From mobly-bundled-snippets with Apache License 2.0 5 votes vote down vote up
/**
 * Enables syncing of a SyncAdapter for a given content provider.
 *
 * <p>Adds the authority to a whitelist, and immediately requests a sync.
 *
 * @param username Username of the account (including @gmail.com).
 * @param authority The authority of a content provider that should be synced.
 */
@Rpc(description = "Enables syncing of a SyncAdapter for a content provider.")
public void startSync(String username, String authority) throws AccountSnippetException {
    if (!listAccounts().contains(username)) {
        throw new AccountSnippetException("Account " + username + " is not on the device");
    }
    // Add to the whitelist
    mLock.writeLock().lock();
    try {
        if (mSyncWhitelist.containsKey(username)) {
            mSyncWhitelist.get(username).add(authority);
        } else {
            mSyncWhitelist.put(username, new HashSet<String>(Arrays.asList(authority)));
        }
        // Update the Sync settings
        for (SyncAdapterType adapter : ContentResolver.getSyncAdapterTypes()) {
            // Find the Google account content provider.
            if (adapter.accountType.equals(GOOGLE_ACCOUNT_TYPE)
                    && adapter.authority.equals(authority)) {
                Account account = new Account(username, GOOGLE_ACCOUNT_TYPE);
                updateSync(account, authority, true);
            }
        }
    } finally {
        mLock.writeLock().unlock();
    }
}
 
Example #7
Source File: ContentService.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
/**
 * Get information about the SyncAdapters that are known to the system for a particular user.
 *
 * <p> If the user id supplied is different to the calling user, the caller must hold the
 * INTERACT_ACROSS_USERS_FULL permission.
 *
 * @return an array of SyncAdapters that have registered with the system
 */
@Override
public SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
    enforceCrossUserPermission(userId,
            "no permission to read sync settings for user " + userId);
    // This makes it so that future permission checks will be in the context of this
    // process rather than the caller's process. We will restore this before returning.
    final long identityToken = clearCallingIdentity();
    try {
        SyncManager syncManager = getSyncManager();
        return syncManager.getSyncAdapterTypes(userId);
    } finally {
        restoreCallingIdentity(identityToken);
    }
}
 
Example #8
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
public SyncAdapterType[] getSyncAdapterTypes(int userId) {
    final Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> serviceInfos;
    serviceInfos = mSyncAdapters.getAllServices(userId);
    SyncAdapterType[] types = new SyncAdapterType[serviceInfos.size()];
    int i = 0;
    for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> serviceInfo : serviceInfos) {
        types[i] = serviceInfo.type;
        ++i;
    }
    return types;
}
 
Example #9
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
public int computeSyncable(Account account, int userId, String authority,
        boolean checkAccountAccess) {
    final int status = getIsSyncable(account, userId, authority);
    if (status == AuthorityInfo.NOT_SYNCABLE) {
        return AuthorityInfo.NOT_SYNCABLE;
    }
    final SyncAdapterType type = SyncAdapterType.newKey(authority, account.type);
    final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
            mSyncAdapters.getServiceInfo(type, userId);
    if (syncAdapterInfo == null) {
        return AuthorityInfo.NOT_SYNCABLE;
    }
    final int owningUid = syncAdapterInfo.uid;
    final String owningPackage = syncAdapterInfo.componentName.getPackageName();
    try {
        if (ActivityManager.getService().isAppStartModeDisabled(owningUid, owningPackage)) {
            Slog.w(TAG, "Not scheduling job " + syncAdapterInfo.uid + ":"
                    + syncAdapterInfo.componentName
                    + " -- package not allowed to start");
            return AuthorityInfo.NOT_SYNCABLE;
        }
    } catch (RemoteException e) {
        /* ignore - local call */
    }
    if (checkAccountAccess && !canAccessAccount(account, owningPackage, owningUid)) {
        Log.w(TAG, "Access to " + logSafe(account) + " denied for package "
                + owningPackage + " in UID " + syncAdapterInfo.uid);
        return AuthorityInfo.SYNCABLE_NO_ACCOUNT_ACCESS;
    }

    return status;
}
 
Example #10
Source File: ContentService.java    From AndroidComponentPlugin with Apache License 2.0 5 votes vote down vote up
/**
 * Get information about the SyncAdapters that are known to the system for a particular user.
 *
 * <p> If the user id supplied is different to the calling user, the caller must hold the
 * INTERACT_ACROSS_USERS_FULL permission.
 *
 * @return an array of SyncAdapters that have registered with the system
 */
@Override
public SyncAdapterType[] getSyncAdapterTypesAsUser(int userId) {
    enforceCrossUserPermission(userId,
            "no permission to read sync settings for user " + userId);
    // This makes it so that future permission checks will be in the context of this
    // process rather than the caller's process. We will restore this before returning.
    final long identityToken = clearCallingIdentity();
    try {
        SyncManager syncManager = getSyncManager();
        return syncManager.getSyncAdapterTypes(userId);
    } finally {
        restoreCallingIdentity(identityToken);
    }
}
 
Example #11
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
OnUnsyncableAccountCheck(
        @NonNull RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo,
        @NonNull OnReadyCallback onReadyCallback) {
    mSyncAdapterInfo = syncAdapterInfo;
    mOnReadyCallback = onReadyCallback;
}
 
Example #12
Source File: SyncManager.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
private boolean dispatchSyncOperation(SyncOperation op) {
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Slog.v(TAG, "dispatchSyncOperation: we are going to sync " + op);
        Slog.v(TAG, "num active syncs: " + mActiveSyncContexts.size());
        for (ActiveSyncContext syncContext : mActiveSyncContexts) {
            Slog.v(TAG, syncContext.toString());
        }
    }
    if (op.isAppStandbyExempted()) {
        final UsageStatsManagerInternal usmi = LocalServices.getService(
                UsageStatsManagerInternal.class);
        if (usmi != null) {
            usmi.reportExemptedSyncStart(op.owningPackage,
                    UserHandle.getUserId(op.owningUid));
        }
    }

    // Connect to the sync adapter.
    int targetUid;
    ComponentName targetComponent;
    final SyncStorageEngine.EndPoint info = op.target;
    SyncAdapterType syncAdapterType =
            SyncAdapterType.newKey(info.provider, info.account.type);
    final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
    syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
    if (syncAdapterInfo == null) {
        mLogger.log("dispatchSyncOperation() failed: no sync adapter info for ",
                syncAdapterType);
        Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
                + ", removing settings for it");
        mSyncStorageEngine.removeAuthority(info);
        return false;
    }
    targetUid = syncAdapterInfo.uid;
    targetComponent = syncAdapterInfo.componentName;
    ActiveSyncContext activeSyncContext =
            new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid);
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Slog.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext);
    }

    activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext);
    mActiveSyncContexts.add(activeSyncContext);

    // Post message to begin monitoring this sync's progress.
    postMonitorSyncProgressMessage(activeSyncContext);

    if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
        mLogger.log("dispatchSyncOperation() failed: bind failed. target: ",
                targetComponent);
        Slog.e(TAG, "Bind attempt failed - target: " + targetComponent);
        closeActiveSyncContext(activeSyncContext);
        return false;
    }

    return true;
}
 
Example #13
Source File: ContentService.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
/**
 * Get information about the SyncAdapters that are known to the system.
 * @return an array of SyncAdapters that have registered with the system
 */
@Override
public SyncAdapterType[] getSyncAdapterTypes() {
    return getSyncAdapterTypesAsUser(UserHandle.getCallingUserId());
}
 
Example #14
Source File: AccountSnippet.java    From mobly-bundled-snippets with Apache License 2.0 4 votes vote down vote up
/**
 * Adds a Google account to the device.
 *
 * @param username Username of the account to add (including @gmail.com).
 * @param password Password of the account to add.
 */
@Rpc(
        description =
                "Add a Google (GMail) account to the device, with account data sync disabled.")
public void addAccount(String username, String password)
        throws AccountSnippetException, AccountsException, IOException {
    // Check for existing account. If we try to re-add an existing account, Android throws an
    // exception that says "Account does not exist or not visible. Maybe change pwd?" which is
    // a little hard to understand.
    if (listAccounts().contains(username)) {
        throw new AccountSnippetException(
                "Account " + username + " already exists on the device");
    }
    Bundle addAccountOptions = new Bundle();
    addAccountOptions.putString("username", username);
    addAccountOptions.putString("password", password);
    AccountManagerFuture<Bundle> future =
            mAccountManager.addAccount(
                    GOOGLE_ACCOUNT_TYPE,
                    AUTH_TOKEN_TYPE,
                    null /* requiredFeatures */,
                    addAccountOptions,
                    null /* activity */,
                    null /* authCallback */,
                    null /* handler */);
    Bundle result = future.getResult();
    if (result.containsKey(AccountManager.KEY_ERROR_CODE)) {
        throw new AccountSnippetException(
                String.format(
                        Locale.US,
                        "Failed to add account due to code %d: %s",
                        result.getInt(AccountManager.KEY_ERROR_CODE),
                        result.getString(AccountManager.KEY_ERROR_MESSAGE)));
    }

    // Disable sync to avoid test flakiness as accounts fetch additional data.
    // It takes a while for all sync adapters to be populated, so register for broadcasts when
    // sync is starting and disable them there.
    // NOTE: this listener is NOT unregistered because several sync requests for the new account
    // will come in over time.
    Account account = new Account(username, GOOGLE_ACCOUNT_TYPE);
    Object handle =
            ContentResolver.addStatusChangeListener(
                    ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE
                            | ContentResolver.SYNC_OBSERVER_TYPE_PENDING,
                    which -> {
                        for (SyncAdapterType adapter : ContentResolver.getSyncAdapterTypes()) {
                            // Ignore non-Google account types.
                            if (!adapter.accountType.equals(GOOGLE_ACCOUNT_TYPE)) {
                                continue;
                            }
                            // If a content provider is not whitelisted, then disable it.
                            // Because startSync and stopSync synchronously update the whitelist
                            // and sync settings, writelock both the whitelist check and the
                            // call to sync together.
                            mLock.writeLock().lock();
                            try {
                                if (!isAdapterWhitelisted(username, adapter.authority)) {
                                    updateSync(account, adapter.authority, false /* sync */);
                                }
                            } finally {
                                mLock.writeLock().unlock();
                            }
                        }
                    });
    mSyncStatusObserverHandles.add(handle);
}
 
Example #15
Source File: ContentService.java    From AndroidComponentPlugin with Apache License 2.0 4 votes vote down vote up
/**
 * Get information about the SyncAdapters that are known to the system.
 * @return an array of SyncAdapters that have registered with the system
 */
@Override
public SyncAdapterType[] getSyncAdapterTypes() {
    return getSyncAdapterTypesAsUser(UserHandle.getCallingUserId());
}
 
Example #16
Source File: ContentService.java    From AndroidComponentPlugin with Apache License 2.0 4 votes vote down vote up
/**
 * Get information about the SyncAdapters that are known to the system.
 * @return an array of SyncAdapters that have registered with the system
 */
@Override
public SyncAdapterType[] getSyncAdapterTypes() {
    return getSyncAdapterTypesAsUser(UserHandle.getCallingUserId());
}
 
Example #17
Source File: XContentResolver.java    From XPrivacy with GNU General Public License v3.0 4 votes vote down vote up
@Override
protected void after(XParam param) throws Throwable {
	switch (mMethod) {
	case getCurrentSync:
		if (isRestricted(param))
			param.setResult(null);
		break;

	case getCurrentSyncs:
		if (isRestricted(param))
			param.setResult(new ArrayList<SyncInfo>());
		break;

	case getSyncAdapterTypes:
		if (isRestricted(param))
			param.setResult(new SyncAdapterType[0]);
		break;

	case openAssetFileDescriptor:
	case openFileDescriptor:
	case openInputStream:
	case openOutputStream:
	case openTypedAssetFileDescriptor:
	case openAssetFile:
	case openFile:
		if (param.args.length > 0 && param.args[0] instanceof Uri) {
			String uri = ((Uri) param.args[0]).toString();
			if (isRestrictedExtra(param, uri))
				param.setThrowable(new FileNotFoundException("XPrivacy"));
		}
		break;

	case Srv_call:
		handleCallAfter(param);
		break;

	case query:
	case Srv_query:
		handleUriAfter(param);
		break;

	case Srv_getCurrentSyncs:
	case Srv_getCurrentSyncsAsUser:
		if (param.getResult() != null)
			if (isRestricted(param)) {
				int uid = Binder.getCallingUid();
				@SuppressWarnings("unchecked")
				List<SyncInfo> listSync = (List<SyncInfo>) param.getResult();
				List<SyncInfo> listFiltered = new ArrayList<SyncInfo>();
				for (SyncInfo sync : listSync)
					if (XAccountManager.isAccountAllowed(sync.account, uid))
						listFiltered.add(sync);
				param.setResult(listFiltered);
			}
		break;
	}
}