diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 95d13519ac331..53f1d19060b8b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -904,6 +904,15 @@ public final class Settings {
public static final String ACTION_APP_NOTIFICATION_SETTINGS
= "android.settings.APP_NOTIFICATION_SETTINGS";
+ /**
+ * Activity Action: Show notification redaction settings.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_APP_NOTIFICATION_REDACTION
+ = "android.settings.ACTION_APP_NOTIFICATION_REDACTION";
+
/** @hide */ public static final String EXTRA_APP_UID = "app_uid";
/** @hide */ public static final String EXTRA_APP_PACKAGE = "app_package";
@@ -3706,6 +3715,14 @@ public final class Settings {
public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
"lock_screen_allow_private_notifications";
+ /**
+ * Set by the system to track if the user needs to see the call to action for
+ * the lockscreen notification policy.
+ * @hide
+ */
+ public static final String SHOW_NOTE_ABOUT_NOTIFICATION_HIDING =
+ "show_note_about_notification_hiding";
+
/**
* The Logging ID (a unique 64-bit value) as a hex string.
* Used as a pseudonymous identifier for logging.
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 299e50cf73f99..a3bed4f8ad3d8 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -187,6 +187,9 @@
1
+
+ true
+
1
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index edefb13ffa5a9..fd5e6fed4f065 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -70,7 +70,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 108;
+ private static final int DATABASE_VERSION = 109;
private Context mContext;
private int mUserHandle;
@@ -1673,8 +1673,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+ " VALUES(?,?);");
- loadBooleanSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- R.bool.def_guest_user_enabled);
+ loadIntegerSetting(stmt, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ R.integer.def_lock_screen_show_notifications);
if (mUserHandle == UserHandle.USER_OWNER) {
final int oldShow = getIntValueFromTable(db,
TABLE_GLOBAL, Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, -1);
@@ -1733,6 +1733,22 @@ public class DatabaseHelper extends SQLiteOpenHelper {
upgradeVersion = 108;
}
+ if (upgradeVersion < 109) {
+ db.beginTransaction();
+ SQLiteStatement stmt = null;
+ try {
+ stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+ + " VALUES(?,?);");
+ loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+ R.bool.def_lock_screen_allow_private_notifications);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ if (stmt != null) stmt.close();
+ }
+ upgradeVersion = 109;
+ }
+
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
@@ -2301,6 +2317,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
R.integer.def_lock_screen_show_notifications);
+ loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+ R.bool.def_lock_screen_allow_private_notifications);
+
} finally {
if (stmt != null) stmt.close();
}
diff --git a/packages/SystemUI/res/drawable/ic_android.xml b/packages/SystemUI/res/drawable/ic_android.xml
new file mode 100644
index 0000000000000..19ee9a7a396b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_android.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_close.xml b/packages/SystemUI/res/drawable/ic_close.xml
new file mode 100644
index 0000000000000..7d93d45dce05d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_close.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 0fe389a7d77ba..3e9a25a28143f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -323,6 +323,15 @@
Signal full.
+
+ On.
+
+ Off.
+
+ Connected.
+
+ Connecting.
+
GPRS
@@ -870,6 +879,18 @@
Device will stay locked until you manually unlock
+
+ Get notifications faster
+
+
+ See them before you unlock
+
+
+ No thanks
+
+
+ Set up
+
Muted by %1$s
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 35ed3e5fe5a87..7889244447003 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -22,6 +22,7 @@ import android.animation.TimeInterpolator;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.app.admin.DevicePolicyManager;
@@ -35,7 +36,11 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
@@ -78,6 +83,7 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.util.NotificationColorUtil;
+import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SearchPanelView;
@@ -126,6 +132,12 @@ public abstract class BaseStatusBar extends SystemUI implements
public static final int EXPANDED_LEAVE_ALONE = -10000;
public static final int EXPANDED_FULL_OPEN = -10001;
+ private static final int HIDDEN_NOTIFICATION_ID = 10000;
+ private static final String BANNER_ACTION_CANCEL =
+ "com.android.systemui.statusbar.banner_action_cancel";
+ private static final String BANNER_ACTION_SETUP =
+ "com.android.systemui.statusbar.banner_action_setup";
+
protected CommandQueue mCommandQueue;
protected IStatusBarService mBarService;
protected H mHandler = createHandler();
@@ -308,6 +320,20 @@ public abstract class BaseStatusBar extends SystemUI implements
mUsersAllowingPrivateNotifications.clear();
updateLockscreenNotificationSetting();
updateNotifications();
+ } else if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
+ NotificationManager noMan = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ noMan.cancel(HIDDEN_NOTIFICATION_ID);
+
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
+ if (BANNER_ACTION_SETUP.equals(action)) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
+ mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+ );
+ }
}
}
};
@@ -490,12 +516,61 @@ public abstract class BaseStatusBar extends SystemUI implements
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(BANNER_ACTION_CANCEL);
+ filter.addAction(BANNER_ACTION_SETUP);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
updateCurrentProfilesCache();
}
+ protected void notifyUserAboutHiddenNotifications() {
+ if (0 != Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 1)) {
+ Log.d(TAG, "user hasn't seen notification about hidden notifications");
+ final LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
+ if (!lockPatternUtils.isSecure()) {
+ Log.d(TAG, "insecure lockscreen, skipping notification");
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
+ return;
+ }
+ Log.d(TAG, "disabling lockecreen notifications and alerting the user");
+ // disable lockscreen notifications until user acts on the banner.
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
+
+ final String packageName = mContext.getPackageName();
+ PendingIntent cancelIntent = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(BANNER_ACTION_CANCEL).setPackage(packageName),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ PendingIntent setupIntent = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(BANNER_ACTION_SETUP).setPackage(packageName),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+
+ final Resources res = mContext.getResources();
+ final int colorRes = com.android.internal.R.color.system_notification_accent_color;
+ Notification.Builder note = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_android)
+ .setContentTitle(mContext.getString(R.string.hidden_notifications_title))
+ .setContentText(mContext.getString(R.string.hidden_notifications_text))
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setOngoing(true)
+ .setColor(res.getColor(colorRes))
+ .setContentIntent(setupIntent)
+ .addAction(R.drawable.ic_close,
+ mContext.getString(R.string.hidden_notifications_cancel),
+ cancelIntent)
+ .addAction(R.drawable.ic_settings,
+ mContext.getString(R.string.hidden_notifications_setup),
+ setupIntent);
+
+ NotificationManager noMan =
+ (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ noMan.notify(HIDDEN_NOTIFICATION_ID, note.build());
+ }
+ }
+
public void userSwitched(int newUserId) {
// should be overridden
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9fd3d9c47d150..d5a8df9fd60a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -582,6 +582,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
putComponent(PhoneStatusBar.class, this);
setControllerUsers();
+
+ notifyUserAboutHiddenNotifications();
}
// ================================================================================