No overlay when permissions shown - framework

bug:26973205

Change-Id: I88395e47649191bb7db6dd8723c49e741ef4f1e4
This commit is contained in:
Svet Ganov
2016-02-16 11:47:00 -08:00
committed by Svetoslav Ganov
parent 7435155432
commit 9cea80cddd
6 changed files with 146 additions and 24 deletions

View File

@@ -1264,6 +1264,14 @@ public class AppOpsManager {
}
}
/** @hide */
public void setUserRestriction(int code, boolean restricted, IBinder token) {
try {
mService.setUserRestriction(code, restricted, token, mContext.getUserId());
} catch (RemoteException e) {
}
}
/** @hide */
public void setMode(int code, int uid, String packageName, int mode) {
try {

View File

@@ -44,6 +44,7 @@ interface IAppOpsService {
int checkAudioOperation(int code, int usage, int uid, String packageName);
void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
void setUserRestrictions(in Bundle restrictions, int userHandle);
void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle);
void removeUser(int userHandle);
}

View File

@@ -2008,6 +2008,12 @@
<permission android:name="android.permission.UPDATE_APP_OPS_STATS"
android:protectionLevel="signature|privileged|installer" />
<!-- Allows an application to update the user app op restrictions.
Not for use by third party apps.
@hide -->
<permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS"
android:protectionLevel="signature|installer" />
<!-- @SystemApi Allows an application to open windows that are for use by parts
of the system user interface.
<p>Not for use by third-party applications.

View File

@@ -31,6 +31,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.AppGlobals;
@@ -67,6 +68,7 @@ import com.android.internal.app.IAppOpsCallback;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import libcore.util.EmptyArray;
@@ -103,9 +105,10 @@ public class AppOpsService extends IAppOpsService.Stub {
}
};
final SparseArray<UidState> mUidStates = new SparseArray<>();
private final SparseArray<UidState> mUidStates = new SparseArray<>();
private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>();
/** These are app op restrictions imposed per user from various parties */
private final ArrayMap<IBinder, SparseArray<boolean[]>> mOpUserRestrictions = new ArrayMap<>();
private static final class UidState {
public final int uid;
@@ -1263,17 +1266,21 @@ public class AppOpsService extends IAppOpsService.Stub {
private boolean isOpRestricted(int uid, int code, String packageName) {
int userHandle = UserHandle.getUserId(uid);
boolean[] opRestrictions = mOpRestrictions.get(userHandle);
if ((opRestrictions != null) && opRestrictions[code]) {
if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
synchronized (this) {
Ops ops = getOpsLocked(uid, packageName, true);
if ((ops != null) && ops.isPrivileged) {
return false;
final int restrictionSetCount = mOpUserRestrictions.size();
for (int i = 0; i < restrictionSetCount; i++) {
SparseArray<boolean[]> perUserRestrictions = mOpUserRestrictions.valueAt(i);
boolean[] opRestrictions = perUserRestrictions.get(userHandle);
if (opRestrictions != null && opRestrictions[code]) {
if (AppOpsManager.opAllowSystemBypassRestriction(code)) {
synchronized (this) {
Ops ops = getOpsLocked(uid, packageName, true);
if ((ops != null) && ops.isPrivileged) {
return false;
}
}
}
return true;
}
return true;
}
return false;
}
@@ -2049,27 +2056,123 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
public void setUserRestrictions(Bundle restrictions, int userHandle) throws RemoteException {
public void setUserRestrictions(Bundle restrictions, IBinder token, int userHandle) {
checkSystemUid("setUserRestrictions");
boolean[] opRestrictions = mOpRestrictions.get(userHandle);
if (opRestrictions == null) {
opRestrictions = new boolean[AppOpsManager._NUM_OP];
mOpRestrictions.put(userHandle, opRestrictions);
}
Preconditions.checkNotNull(token);
final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle);
for (int i = 0; i < opRestrictions.length; ++i) {
String restriction = AppOpsManager.opToRestriction(i);
if (restriction != null) {
opRestrictions[i] = restrictions.getBoolean(restriction, false);
} else {
opRestrictions[i] = false;
final boolean restricted = restriction != null
&& restrictions.getBoolean(restriction, false);
setUserRestrictionNoCheck(i, restricted, token, userHandle);
}
}
@Override
public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
}
if (userHandle != UserHandle.getCallingUserId()) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission
.INTERACT_ACROSS_USERS_FULL) != PackageManager.PERMISSION_GRANTED
&& mContext.checkCallingOrSelfPermission(Manifest.permission
.INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Need INTERACT_ACROSS_USERS_FULL or"
+ " INTERACT_ACROSS_USERS to interact cross user ");
}
}
verifyIncomingOp(code);
Preconditions.checkNotNull(token);
setUserRestrictionNoCheck(code, restricted, token, userHandle);
}
private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token,
int userHandle) {
final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle);
if (opRestrictions[code] == restricted) {
return;
}
opRestrictions[code] = restricted;
if (!restricted) {
pruneUserRestrictionsForToken(token, userHandle);
}
final ArrayList<Callback> clonedCallbacks;
synchronized (this) {
ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
if (callbacks == null) {
return;
}
clonedCallbacks = new ArrayList<>(callbacks);
}
// There are components watching for mode changes such as window manager
// and location manager which are in our process. The callbacks in these
// components may require permissions our remote caller does not have.
final long identity = Binder.clearCallingIdentity();
try {
final int callbackCount = clonedCallbacks.size();
for (int i = 0; i < callbackCount; i++) {
Callback callback = clonedCallbacks.get(i);
try {
callback.mCallback.opChanged(code, -1, null);
} catch (RemoteException e) {
Log.w(TAG, "Error dispatching op op change", e);
}
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
@Override
public void removeUser(int userHandle) throws RemoteException {
checkSystemUid("removeUser");
mOpRestrictions.remove(userHandle);
final int tokenCount = mOpUserRestrictions.size();
for (int i = tokenCount - 1; i >= 0; i--) {
SparseArray<boolean[]> opRestrictions = mOpUserRestrictions.valueAt(i);
if (opRestrictions != null) {
opRestrictions.remove(userHandle);
if (opRestrictions.size() <= 0) {
mOpUserRestrictions.removeAt(i);
}
}
}
}
private void pruneUserRestrictionsForToken(IBinder token, int userHandle) {
SparseArray<boolean[]> perTokenRestrictions = mOpUserRestrictions.get(token);
if (perTokenRestrictions != null) {
final boolean[] opRestrictions = perTokenRestrictions.get(userHandle);
if (opRestrictions != null) {
for (boolean restriction : opRestrictions) {
if (restriction) {
return;
}
}
perTokenRestrictions.remove(userHandle);
if (perTokenRestrictions.size() <= 0) {
mOpUserRestrictions.remove(token);
}
}
}
}
private boolean[] getOrCreateUserRestrictionsForToken(IBinder token, int userHandle) {
SparseArray<boolean[]> perTokenRestrictions = mOpUserRestrictions.get(token);
if (perTokenRestrictions == null) {
perTokenRestrictions = new SparseArray<>();
mOpUserRestrictions.put(token, perTokenRestrictions);
}
boolean[] opRestrictions = perTokenRestrictions.get(userHandle);
if (opRestrictions == null) {
opRestrictions = new boolean[AppOpsManager._NUM_OP];
perTokenRestrictions.put(userHandle, opRestrictions);
}
return opRestrictions;
}
private void checkSystemUid(String function) {

View File

@@ -41,6 +41,7 @@ import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
import android.os.IUserManager;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -188,6 +189,8 @@ public class UserManagerService extends IUserManager.Stub {
private final File mUsersDir;
private final File mUserListFile;
private static final IBinder mUserRestriconToken = new Binder();
/**
* User-related information that is used for persisting to flash. Only UserInfo is
* directly exposed to other system apps.
@@ -1016,7 +1019,7 @@ public class UserManagerService extends IUserManager.Stub {
if (mAppOpsService != null) { // We skip it until system-ready.
final long token = Binder.clearCallingIdentity();
try {
mAppOpsService.setUserRestrictions(effective, userId);
mAppOpsService.setUserRestrictions(effective, mUserRestriconToken, userId);
} catch (RemoteException e) {
Log.w(LOG_TAG, "Unable to notify AppOpsService of UserRestrictions");
} finally {

View File

@@ -33,6 +33,7 @@ import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManager.StackId;
import android.app.ActivityManagerInternal;
@@ -2035,7 +2036,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
}
if (permission != null) {
if (permission == android.Manifest.permission.SYSTEM_ALERT_WINDOW) {
if (android.Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permission)) {
final int callingUid = Binder.getCallingUid();
// system processes will be automatically allowed privilege to draw
if (callingUid == Process.SYSTEM_UID) {