summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Franz <bfranz@google.com>2015-03-16 17:18:09 +0000
committerBenjamin Franz <bfranz@google.com>2015-04-15 15:57:14 +0100
commitea2ec97f37c649881f2be8a5cc40bf44080cc632 (patch)
tree25a5c8898f63b736c73cdb18add1e4b3ef1df67f
parentde77be631184ff1204017c3d8996d7c71aa5cf02 (diff)
downloadframeworks_base-ea2ec97f37c649881f2be8a5cc40bf44080cc632.zip
frameworks_base-ea2ec97f37c649881f2be8a5cc40bf44080cc632.tar.gz
frameworks_base-ea2ec97f37c649881f2be8a5cc40bf44080cc632.tar.bz2
Introduce device owner API to disable the status bar
Let the device owner disable the status bar to achieve multi-app single purpose mode. When the status bar is disabled, quick settings, notifications and the assist gesture are blocked. Bug: 19533026 Change-Id: I72830798135136e5edc53e5e2221aebb9a7c7d57
-rw-r--r--api/current.txt1
-rw-r--r--api/system-current.txt1
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java16
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl1
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java7
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java72
7 files changed, 91 insertions, 8 deletions
diff --git a/api/current.txt b/api/current.txt
index ea4aaf9..d2d7d95 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5737,6 +5737,7 @@ package android.app.admin {
method public void setRestrictionsProvider(android.content.ComponentName, android.content.ComponentName);
method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
+ method public void setStatusBarEnabledState(android.content.ComponentName, boolean);
method public int setStorageEncryption(android.content.ComponentName, boolean);
method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 1a28546..fcb2ce6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5841,6 +5841,7 @@ package android.app.admin {
method public void setRestrictionsProvider(android.content.ComponentName, android.content.ComponentName);
method public void setScreenCaptureDisabled(android.content.ComponentName, boolean);
method public void setSecureSetting(android.content.ComponentName, java.lang.String, java.lang.String);
+ method public void setStatusBarEnabledState(android.content.ComponentName, boolean);
method public int setStorageEncryption(android.content.ComponentName, boolean);
method public void setTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
method public void setUninstallBlocked(android.content.ComponentName, java.lang.String, boolean);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index a0a6c4c..44760ce 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4210,4 +4210,20 @@ public class DevicePolicyManager {
return false;
}
}
+
+ /**
+ * Called by device owner to set the enabled state of the status bar. Disabling the status
+ * bar blocks notifications, quick settings and other screen overlays that allow escaping from
+ * a single use device.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param enabled New state of the status bar.
+ */
+ public void setStatusBarEnabledState(ComponentName admin, boolean enabled) {
+ try {
+ mService.setStatusBarEnabledState(admin, enabled);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed talking with device policy service", re);
+ }
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 131b99c..7502e1d 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -223,4 +223,5 @@ interface IDevicePolicyManager {
PersistableBundle getOtaPolicy();
boolean setKeyguardEnabledState(in ComponentName admin, boolean enabled);
+ void setStatusBarEnabledState(in ComponentName who, boolean enabled);
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 6cb839e..87e0603 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -27,6 +27,7 @@ interface IStatusBarService
void expandNotificationsPanel();
void collapsePanels();
void disable(int what, IBinder token, String pkg);
+ void disableForUser(int what, IBinder token, String pkg, int userId);
void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
void setIconVisibility(String slot, boolean visible);
void removeIcon(String slot);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index f6df757..184224b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -79,7 +79,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
public void binderDied() {
Slog.i(TAG, "binder died for pkg=" + pkg);
- disableInternal(userId, 0, token, pkg);
+ disableForUser(0, token, pkg, userId);
token.unlinkToDeath(this, 0);
}
}
@@ -194,10 +194,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
@Override
public void disable(int what, IBinder token, String pkg) {
- disableInternal(mCurrentUserId, what, token, pkg);
+ disableForUser(what, token, pkg, mCurrentUserId);
}
- private void disableInternal(int userId, int what, IBinder token, String pkg) {
+ @Override
+ public void disableForUser(int what, IBinder token, String pkg, int userId) {
enforceStatusBar();
synchronized (mLock) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c7d2b86..fcf6189 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -32,6 +32,7 @@ import android.app.IActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.StatusBarManager;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
@@ -102,6 +103,7 @@ import android.view.IWindowManager;
import com.android.internal.R;
import com.android.internal.os.storage.ExternalStorageFormatter;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.Preconditions;
@@ -152,7 +154,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private static final String DEVICE_POLICIES_XML = "device_policies.xml";
- private static final String LOCK_TASK_COMPONENTS_XML = "lock-task-component";
+ private static final String TAG_LOCK_TASK_COMPONENTS = "lock-task-component";
+
+ private static final String TAG_STATUS_BAR = "statusbar";
+
+ private static final String ATTR_ENABLED = "enabled";
private static final int REQUEST_EXPIRE_PASSWORD = 5571;
@@ -172,6 +178,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer";
+ private static final int STATUS_BAR_DISABLE_MASK =
+ StatusBarManager.DISABLE_EXPAND |
+ StatusBarManager.DISABLE_NOTIFICATION_ICONS |
+ StatusBarManager.DISABLE_NOTIFICATION_ALERTS |
+ StatusBarManager.DISABLE_SEARCH;
+
private static final Set<String> DEVICE_OWNER_USER_RESTRICTIONS;
static {
DEVICE_OWNER_USER_RESTRICTIONS = new HashSet();
@@ -237,6 +249,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// Stores and loads state on device and profile owners.
private DeviceOwner mDeviceOwner;
+ private final Binder mToken = new Binder();
+
/**
* Whether or not device admin feature is supported. If it isn't return defaults for all
* public methods.
@@ -287,6 +301,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// This is the list of component allowed to start lock task mode.
final List<String> mLockTaskPackages = new ArrayList<>();
+ boolean mStatusBarEnabledState = true;
+
ComponentName mRestrictionsProvider;
String mDelegatedCertInstallerPackage;
@@ -1429,9 +1445,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
for (int i=0; i<policy.mLockTaskPackages.size(); i++) {
String component = policy.mLockTaskPackages.get(i);
- out.startTag(null, LOCK_TASK_COMPONENTS_XML);
+ out.startTag(null, TAG_LOCK_TASK_COMPONENTS);
out.attribute(null, "name", component);
- out.endTag(null, LOCK_TASK_COMPONENTS_XML);
+ out.endTag(null, TAG_LOCK_TASK_COMPONENTS);
+ }
+
+ if (!policy.mStatusBarEnabledState) {
+ out.startTag(null, TAG_STATUS_BAR);
+ out.attribute(null, ATTR_ENABLED, Boolean.toString(policy.mStatusBarEnabledState));
+ out.endTag(null, TAG_STATUS_BAR);
}
out.endTag(null, "policies");
@@ -1552,9 +1574,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy.mActivePasswordNonLetter = Integer.parseInt(
parser.getAttributeValue(null, "nonletter"));
XmlUtils.skipCurrentTag(parser);
- } else if (LOCK_TASK_COMPONENTS_XML.equals(tag)) {
+ } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) {
policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name"));
XmlUtils.skipCurrentTag(parser);
+ } else if (TAG_STATUS_BAR.equals(tag)) {
+ policy.mStatusBarEnabledState = Boolean.parseBoolean(
+ parser.getAttributeValue(null, ATTR_ENABLED));
+ XmlUtils.skipCurrentTag(parser);
} else {
Slog.w(LOG_TAG, "Unknown tag: " + tag);
XmlUtils.skipCurrentTag(parser);
@@ -1679,7 +1705,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return;
}
- getUserData(UserHandle.USER_OWNER);
+ DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
loadDeviceOwner();
cleanUpOldUsers();
// Register an observer for watching for user setup complete.
@@ -1696,6 +1722,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
getScreenCaptureDisabled(null, userHandle));
}
+ if (mDeviceOwner != null && mDeviceOwner.hasDeviceOwner()
+ && !policy.mStatusBarEnabledState) {
+ setStatusBarEnabledStateInternal(STATUS_BAR_DISABLE_MASK, UserHandle.USER_OWNER);
+ }
}
private void cleanUpOldUsers() {
@@ -5830,6 +5860,38 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return true;
}
+ @Override
+ public void setStatusBarEnabledState(ComponentName who, boolean enabled) {
+ int userId = UserHandle.getCallingUserId();
+ synchronized (this) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ DevicePolicyData policy = getUserData(userId);
+ if (policy.mStatusBarEnabledState != enabled) {
+ policy.mStatusBarEnabledState = enabled;
+ setStatusBarEnabledStateInternal(
+ enabled ? StatusBarManager.DISABLE_NONE : STATUS_BAR_DISABLE_MASK,
+ userId);
+ saveSettingsLocked(userId);
+ }
+ }
+ }
+
+ private void setStatusBarEnabledStateInternal(int flags, int userId) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ IStatusBarService statusBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.checkService(Context.STATUS_BAR_SERVICE));
+ if (statusBarService != null) {
+ statusBarService.disableForUser(flags, mToken,
+ mDeviceOwner.getDeviceOwnerPackageName(), userId);
+ }
+ } catch (RemoteException e) {
+ Slog.e(LOG_TAG, "Failed to disable the status bar", e);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
/**
* We need to update the internal state of whether a user has completed setup once. After
* that, we ignore any changes that reset the Settings.Secure.USER_SETUP_COMPLETE changes