blob: 9c48b43c216f245e3a0640746ecf73056ade5785 [file] [log] [blame]
/*
* Copyright (C) 2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.storagemanager.automatic;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.provider.Settings;
import com.android.storagemanager.R;
import java.util.concurrent.TimeUnit;
/**
* NotificationController handles the responses to the Automatic Storage Management low storage
* notification.
*/
public class NotificationController extends BroadcastReceiver {
/**
* Intent action for if the user taps "Turn on" for the automatic storage manager.
*/
public static final String INTENT_ACTION_ACTIVATE_ASM =
"com.android.storagemanager.automatic.ACTIVATE";
/**
* Intent action for if the user swipes the notification away.
*/
public static final String INTENT_ACTION_DISMISS =
"com.android.storagemanager.automatic.DISMISS";
/**
* Intent action for if the user explicitly hits "No thanks" on the notification.
*/
public static final String INTENT_ACTION_NO_THANKS =
"com.android.storagemanager.automatic.NO_THANKS";
/**
* Intent action for forcefully showing the notification, even if the conditions are not valid.
*/
private static final String INTENT_ACTION_DEBUG_NOTIFICATION =
"com.android.storagemanager.automatic.DEBUG_SHOW_NOTIFICATION";
/**
* Intent action for if the user taps on the notification.
*/
private static final String INTENT_ACTION_TAP =
"com.android.storagemanager.automatic.SHOW_SETTINGS";
/**
* Intent extra for the notification id.
*/
public static final String INTENT_EXTRA_ID = "id";
private static final String SHARED_PREFERENCES_NAME = "NotificationController";
private static final String NOTIFICATION_NEXT_SHOW_TIME = "notification_next_show_time";
private static final String NOTIFICATION_SHOWN_COUNT = "notification_shown_count";
private static final long DISMISS_DELAY = TimeUnit.DAYS.toMillis(15);
private static final long NO_THANKS_DELAY = TimeUnit.DAYS.toMillis(90);
private static final long MAXIMUM_SHOWN_COUNT = 4;
private static final int NOTIFICATION_ID = 0;
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case INTENT_ACTION_ACTIVATE_ASM:
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
1);
break;
case INTENT_ACTION_NO_THANKS:
delayNextNotification(context, NO_THANKS_DELAY);
break;
case INTENT_ACTION_DISMISS:
delayNextNotification(context, DISMISS_DELAY);
break;
case INTENT_ACTION_DEBUG_NOTIFICATION:
showNotification(context);
return;
case INTENT_ACTION_TAP:
Intent storageIntent = new Intent(Settings.ACTION_STORAGE_MANAGER_SETTINGS);
storageIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(storageIntent);
break;
}
cancelNotification(context, intent);
}
/**
* If the conditions for showing the activation notification are met, show the activation
* notification.
* @param context Context to use for getting resources and to display the notification.
*/
public static void maybeShowNotification(Context context) {
if (shouldShowNotification(context)) {
showNotification(context);
}
}
private static boolean shouldShowNotification(Context context) {
SharedPreferences sp = context.getSharedPreferences(
SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE);
int timesShown = sp.getInt(NOTIFICATION_SHOWN_COUNT, 0);
if (timesShown > MAXIMUM_SHOWN_COUNT) {
return false;
}
long nextTimeToShow = sp.getLong(NOTIFICATION_NEXT_SHOW_TIME, 0);
return System.currentTimeMillis() > nextTimeToShow;
}
private static void showNotification(Context context) {
Resources res = context.getResources();
Intent noThanksIntent = new Intent(INTENT_ACTION_NO_THANKS);
noThanksIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
Notification.Action.Builder cancelAction = new Notification.Action.Builder(null,
res.getString(R.string.automatic_storage_manager_cancel_button),
PendingIntent.getBroadcast(context, 0, noThanksIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
Intent activateIntent = new Intent(INTENT_ACTION_ACTIVATE_ASM);
activateIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
Notification.Action.Builder activateAutomaticAction = new Notification.Action.Builder(null,
res.getString(R.string.automatic_storage_manager_activate_button),
PendingIntent.getBroadcast(context, 0, activateIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
Intent dismissIntent = new Intent(INTENT_ACTION_DISMISS);
dismissIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
PendingIntent deleteIntent = PendingIntent.getBroadcast(context, 0,
new Intent(INTENT_ACTION_DISMISS),
PendingIntent.FLAG_ONE_SHOT);
Intent contentIntent = new Intent(INTENT_ACTION_TAP);
contentIntent.putExtra(INTENT_EXTRA_ID, NOTIFICATION_ID);
PendingIntent tapIntent = PendingIntent.getBroadcast(context, 0, contentIntent,
PendingIntent.FLAG_ONE_SHOT);
Notification.Builder builder = new Notification.Builder(context)
.setSmallIcon(R.drawable.ic_settings_24dp)
.setContentTitle(
res.getString(R.string.automatic_storage_manager_notification_title))
.setContentText(
res.getString(R.string.automatic_storage_manager_notification_summary))
.setStyle(new Notification.BigTextStyle().bigText(
res.getString(R.string.automatic_storage_manager_notification_summary)))
.addAction(cancelAction.build())
.addAction(activateAutomaticAction.build())
.setContentIntent(tapIntent)
.setDeleteIntent(deleteIntent);
NotificationManager manager =
((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
manager.notify(NOTIFICATION_ID, builder.build());
}
private void cancelNotification(Context context, Intent intent) {
int id = intent.getIntExtra(INTENT_EXTRA_ID, -1);
if (id == -1) {
return;
}
NotificationManager manager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(id);
incrementNotificationShownCount(context);
}
private void incrementNotificationShownCount(Context context) {
SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
int shownCount = sp.getInt(NotificationController.NOTIFICATION_SHOWN_COUNT, 0) + 1;
editor.putInt(NotificationController.NOTIFICATION_SHOWN_COUNT, shownCount);
editor.apply();
}
private void delayNextNotification(Context context, long timeInMillis) {
SharedPreferences sp = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putLong(NOTIFICATION_NEXT_SHOW_TIME,
System.currentTimeMillis() + timeInMillis);
editor.apply();
}
}