Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3c638a4 authored by Russell Brenner's avatar Russell Brenner Committed by Android Git Automerger
Browse files

Merge branch 'lmp-dev' of...

parents 81dca120 948397a4
Loading
Loading
Loading
Loading
+42 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.database;

import android.net.Uri;
import android.os.Handler;
import android.os.UserHandle;

/**
 * Receives call backs for changes to content.
@@ -129,6 +130,21 @@ public abstract class ContentObserver {
        onChange(selfChange);
    }

    /**
     * Dispatches a change notification to the observer. Includes the changed
     * content Uri when available and also the user whose content changed.
     *
     * @param selfChange True if this is a self-change notification.
     * @param uri The Uri of the changed content, or null if unknown.
     * @param userId The user whose content changed. Can be either a specific
     *         user or {@link UserHandle#USER_ALL}.
     *
     * @hide
     */
    public void onChange(boolean selfChange, Uri uri, int userId) {
        onChange(selfChange, uri);
    }

    /**
     * Dispatches a change notification to the observer.
     * <p>
@@ -159,25 +175,45 @@ public abstract class ContentObserver {
     * @param uri The Uri of the changed content, or null if unknown.
     */
    public final void dispatchChange(boolean selfChange, Uri uri) {
        dispatchChange(selfChange, uri, UserHandle.getCallingUserId());
    }

    /**
     * Dispatches a change notification to the observer. Includes the changed
     * content Uri when available and also the user whose content changed.
     * <p>
     * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
     * then a call to the {@link #onChange} method is posted to the handler's message queue.
     * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
     * </p>
     *
     * @param selfChange True if this is a self-change notification.
     * @param uri The Uri of the changed content, or null if unknown.
     * @param userId The user whose content changed.
     */
    private void dispatchChange(boolean selfChange, Uri uri, int userId) {
        if (mHandler == null) {
            onChange(selfChange, uri);
            onChange(selfChange, uri, userId);
        } else {
            mHandler.post(new NotificationRunnable(selfChange, uri));
            mHandler.post(new NotificationRunnable(selfChange, uri, userId));
        }
    }


    private final class NotificationRunnable implements Runnable {
        private final boolean mSelfChange;
        private final Uri mUri;
        private final int mUserId;

        public NotificationRunnable(boolean selfChange, Uri uri) {
        public NotificationRunnable(boolean selfChange, Uri uri, int userId) {
            mSelfChange = selfChange;
            mUri = uri;
            mUserId = userId;
        }

        @Override
        public void run() {
            ContentObserver.this.onChange(mSelfChange, mUri);
            ContentObserver.this.onChange(mSelfChange, mUri, mUserId);
        }
    }

@@ -189,10 +225,10 @@ public abstract class ContentObserver {
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
        public void onChange(boolean selfChange, Uri uri, int userId) {
            ContentObserver contentObserver = mContentObserver;
            if (contentObserver != null) {
                contentObserver.dispatchChange(selfChange, uri);
                contentObserver.dispatchChange(selfChange, uri, userId);
            }
        }

+4 −6
Original line number Diff line number Diff line
@@ -17,9 +17,7 @@
package android.database;

import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.*;


/**
@@ -80,7 +78,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            try {
                mRemote.onChange(selfChange, uri);
                mRemote.onChange(selfChange, uri, android.os.Process.myUid());
            } catch (RemoteException ex) {
                // Do nothing, the far side is dead
            }
+9 −9
Original line number Diff line number Diff line
@@ -2,8 +2,8 @@
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** 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
@@ -29,5 +29,5 @@ interface IContentObserver
     * observed. selfUpdate is true if the update was caused by a call to
     * commit on the cursor that is being observed.
     */
    oneway void onChange(boolean selfUpdate, in Uri uri);
    oneway void onChange(boolean selfUpdate, in Uri uri, int userId);
}
+1 −1
Original line number Diff line number Diff line
@@ -255,7 +255,7 @@ public final class ContentService extends IContentService.Stub {
            for (int i=0; i<numCalls; i++) {
                ObserverCall oc = calls.get(i);
                try {
                    oc.mObserver.onChange(oc.mSelfChange, uri);
                    oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                        Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri);
                    }
+58 −103
Original line number Diff line number Diff line
@@ -17,14 +17,14 @@
package com.android.server.print;

import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -81,10 +81,13 @@ public final class PrintManagerService extends SystemService {
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            mPrintManagerImpl.systemRunning();
    public void onStartUser(int userHandle) {
        mPrintManagerImpl.handleUserStarted(userHandle);
    }

    @Override
    public void onStopUser(int userHandle) {
        mPrintManagerImpl.handleUserStopped(userHandle);
    }

    class PrintManagerImpl extends IPrintManager.Stub {
@@ -101,9 +104,7 @@ public final class PrintManagerService extends SystemService {

        private final UserManager mUserManager;

        private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();

        private int mCurrentUserId = UserHandle.USER_OWNER;
        private final SparseArray<UserState> mUserStates = new SparseArray<>();

        PrintManagerImpl(Context context) {
            mContext = context;
@@ -112,22 +113,6 @@ public final class PrintManagerService extends SystemService {
            registerBroadcastReceivers();
        }

        public void systemRunning() {
            BackgroundThread.getHandler().post(new Runnable() {
                @Override
                public void run() {
                    final UserState userState;
                    synchronized (mLock) {
                        userState = getCurrentUserStateLocked();
                    }
                    // This is the first time we switch to this user after boot, so
                    // now is the time to remove obsolete print jobs since they
                    // are from the last boot and no application would query them.
                    userState.removeObsoletePrintJobs();
                }
            });
        }

        @Override
        public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
                PrintAttributes attributes, String packageName, int appId, int userId) {
@@ -137,7 +122,7 @@ public final class PrintManagerService extends SystemService {
            final String resolvedPackageName;
            synchronized (mLock) {
                // Only the current group members can start new print jobs.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return null;
                }
                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -160,7 +145,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can query for state of print jobs.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return null;
                }
                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -181,7 +166,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can query for state of a print job.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return null;
                }
                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -202,7 +187,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can cancel a print job.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -223,7 +208,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can restart a print job.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -243,7 +228,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can get enabled services.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return null;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -262,7 +247,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can get installed services.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return null;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -282,7 +267,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can create a discovery session.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -302,7 +287,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can destroy a discovery session.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -322,7 +307,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can start discovery.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -341,7 +326,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can stop discovery.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -360,7 +345,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can validate printers.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -379,7 +364,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can start printer tracking.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -398,7 +383,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can stop printer tracking.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -419,7 +404,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can add a print job listener.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -440,7 +425,7 @@ public final class PrintManagerService extends SystemService {
            final UserState userState;
            synchronized (mLock) {
                // Only the current group members can remove a print job listener.
                if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
                if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
                    return;
                }
                userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -484,14 +469,22 @@ public final class PrintManagerService extends SystemService {
                    Settings.Secure.ENABLED_PRINT_SERVICES);
            ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) {
                @Override
                public void onChange(boolean selfChange, Uri uri) {
                public void onChange(boolean selfChange, Uri uri, int userId) {
                    if (enabledPrintServicesUri.equals(uri)) {
                        synchronized (mLock) {
                            UserState userState = getCurrentUserStateLocked();
                            if (userId != UserHandle.USER_ALL) {
                                UserState userState = getOrCreateUserStateLocked(userId);
                                userState.updateIfNeededLocked();
                            } else {
                                final int userCount = mUserStates.size();
                                for (int i = 0; i < userCount; i++) {
                                    UserState userState = mUserStates.valueAt(i);
                                    userState.updateIfNeededLocked();
                                }
                            }
                        }
                    }
                }
            };

            mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri,
@@ -622,27 +615,6 @@ public final class PrintManagerService extends SystemService {
            // package changes
            monitor.register(mContext, BackgroundThread.getHandler().getLooper(),
                    UserHandle.ALL, true);

            // user changes
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
            intentFilter.addAction(Intent.ACTION_USER_REMOVED);

            mContext.registerReceiverAsUser(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                        switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
                    } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                        removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
                    }
                }
            }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler());
        }

        private UserState getCurrentUserStateLocked() {
            return getOrCreateUserStateLocked(mCurrentUserId);
        }

        private UserState getOrCreateUserStateLocked(int userId) {
@@ -654,20 +626,11 @@ public final class PrintManagerService extends SystemService {
            return userState;
        }

        private void switchUser(int newUserId) {
        private void handleUserStarted(int userId) {
            UserState userState;
            synchronized (mLock) {
                if (newUserId == mCurrentUserId) {
                    return;
                }
                mCurrentUserId = newUserId;
                userState = mUserStates.get(mCurrentUserId);
                if (userState == null) {
                    userState = getCurrentUserStateLocked();
                userState = getOrCreateUserStateLocked(userId);
                userState.updateIfNeededLocked();
                } else {
                    userState.updateIfNeededLocked();
                }
            }
            // This is the first time we switch to this user after boot, so
            // now is the time to remove obsolete print jobs since they
@@ -675,18 +638,18 @@ public final class PrintManagerService extends SystemService {
            userState.removeObsoletePrintJobs();
        }

        private void removeUser(int removedUserId) {
        private void handleUserStopped(int userId) {
            synchronized (mLock) {
                UserState userState = mUserStates.get(removedUserId);
                UserState userState = mUserStates.get(userId);
                if (userState != null) {
                    userState.destroyLocked();
                    mUserStates.remove(removedUserId);
                    mUserStates.remove(userId);
                }
            }
        }

        private int resolveCallingProfileParentLocked(int userId) {
            if (userId != mCurrentUserId) {
            if (userId != getCurrentUserId()) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    UserInfo parent = mUserManager.getProfileParent(userId);
@@ -723,28 +686,11 @@ public final class PrintManagerService extends SystemService {
        }

        private int resolveCallingUserEnforcingPermissions(int userId) {
            final int callingUid = Binder.getCallingUid();
            if (callingUid == 0 || callingUid == Process.SYSTEM_UID
                    || callingUid == Process.SHELL_UID) {
                return userId;
            }
            final int callingUserId = UserHandle.getUserId(callingUid);
            if (callingUserId == userId) {
                return userId;
            }
            if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                    != PackageManager.PERMISSION_GRANTED
                &&  mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
                    != PackageManager.PERMISSION_GRANTED) {
                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
                    return callingUserId;
                }
                throw new SecurityException("Call from user " + callingUserId + " as user "
                    + userId + " without permission INTERACT_ACROSS_USERS or "
                    + "INTERACT_ACROSS_USERS_FULL not allowed.");
            }
            if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) {
                return mCurrentUserId;
            try {
                return ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
                        Binder.getCallingUid(), userId, true, true, "", null);
            } catch (RemoteException re) {
                // Shouldn't happen, local.
            }
            return userId;
        }
@@ -764,6 +710,15 @@ public final class PrintManagerService extends SystemService {
            return null;
        }

        private int getCurrentUserId () {
            final long identity = Binder.clearCallingIdentity();
            try {
                return ActivityManager.getCurrentUser();
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }

        private void showEnableInstalledPrintServiceNotification(ComponentName component,
                String label, int userId) {
            UserHandle userHandle = new UserHandle(userId);