1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.storagemanager.deletionhelper; 16 17 import android.app.Activity; 18 import android.app.AlertDialog; 19 import android.app.Dialog; 20 import android.app.DialogFragment; 21 import android.content.Context; 22 import android.content.DialogInterface; 23 import android.content.SharedPreferences; 24 import android.os.Bundle; 25 import android.provider.Settings; 26 import android.text.format.Formatter; 27 import com.android.storagemanager.R; 28 29 import java.util.concurrent.TimeUnit; 30 31 /** 32 * Fragment for activating the storage manager after a manual clear. 33 */ 34 public class StorageManagerUpsellDialog extends DialogFragment 35 implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { 36 public static final String TAG = "StorageManagerUpsellDialog"; 37 private static final String SHARED_PREFERENCES_NAME = "StorageManagerUpsellDialog"; 38 private static final String NEXT_SHOW_TIME = "next_show_time"; 39 private static final String DISMISSED_COUNT = "dismissed_count"; 40 private static final String NO_THANKS_COUNT = "no_thanks_count"; 41 42 private static final String ARGS_FREED_BYTES = "freed_bytes"; 43 44 private static final long NEVER = -1; 45 private static final long DISMISS_SHORT_DELAY = TimeUnit.DAYS.toMillis(14); 46 private static final long DISMISS_LONG_DELAY = TimeUnit.DAYS.toMillis(90); 47 private static final int DISMISS_LONG_THRESHOLD = 9; 48 private static final long NO_THANKS_SHORT_DELAY = TimeUnit.DAYS.toMillis(90); 49 private static final long NO_THANKS_LONG_DELAY = NEVER; 50 private static final int NO_THANKS_LONG_THRESHOLD = 3; 51 newInstance(long freedBytes)52 public static StorageManagerUpsellDialog newInstance(long freedBytes) { 53 StorageManagerUpsellDialog dialog = new StorageManagerUpsellDialog(); 54 Bundle args = new Bundle(1); 55 args.putLong(ARGS_FREED_BYTES, freedBytes); 56 dialog.setArguments(args); 57 return dialog; 58 } 59 60 @Override onCreateDialog(Bundle savedInstanceState)61 public Dialog onCreateDialog(Bundle savedInstanceState) { 62 final Bundle args = getArguments(); 63 long freedBytes = args.getLong(ARGS_FREED_BYTES); 64 65 final Context context = getContext(); 66 return new AlertDialog.Builder(context) 67 .setTitle(context.getString(R.string.deletion_helper_upsell_title)) 68 .setMessage(context.getString(R.string.deletion_helper_upsell_summary, 69 Formatter.formatFileSize(context, freedBytes))) 70 .setPositiveButton(R.string.deletion_helper_upsell_activate, this) 71 .setNegativeButton(R.string.deletion_helper_upsell_cancel, this) 72 .create(); 73 } 74 75 @Override onClick(DialogInterface dialog, int buttonId)76 public void onClick(DialogInterface dialog, int buttonId) { 77 if (buttonId == DialogInterface.BUTTON_POSITIVE) { 78 Settings.Secure.putInt(getActivity().getContentResolver(), 79 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 1); 80 } else { 81 SharedPreferences sp = getSharedPreferences(getContext()); 82 int noThanksCount = sp.getInt(NO_THANKS_COUNT, 0) + 1; 83 SharedPreferences.Editor editor = sp.edit(); 84 editor.putInt(NO_THANKS_COUNT, noThanksCount); 85 editor.putLong(NEXT_SHOW_TIME, 86 System.currentTimeMillis() + getNoThanksDelay(noThanksCount)); 87 editor.apply(); 88 } 89 90 finishActivity(); 91 } 92 93 @Override onCancel(DialogInterface dialog)94 public void onCancel(DialogInterface dialog) { 95 SharedPreferences sp = getSharedPreferences(getContext()); 96 int dismissCount = sp.getInt(DISMISSED_COUNT, 0) + 1; 97 SharedPreferences.Editor editor = sp.edit(); 98 editor.putInt(DISMISSED_COUNT, dismissCount); 99 editor.putLong(NEXT_SHOW_TIME, 100 System.currentTimeMillis() + getDismissDelay(dismissCount)); 101 editor.apply(); 102 103 finishActivity(); 104 } 105 106 /** 107 * Returns if the dialog should be shown, given the delays between when it is shown. 108 * @param context Context to get shared preferences for determining the next show time. 109 */ shouldShow(Context context)110 public static boolean shouldShow(Context context) { 111 boolean isEnabled = 112 Settings.Secure.getInt(context.getContentResolver(), 113 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0; 114 if (isEnabled) { 115 return false; 116 } 117 118 long nextTimeToShow = getSharedPreferences(context).getLong(NEXT_SHOW_TIME, 0); 119 120 if (nextTimeToShow == NEVER) { 121 return false; 122 } 123 124 return System.currentTimeMillis() > nextTimeToShow; 125 } 126 getSharedPreferences(Context context)127 private static SharedPreferences getSharedPreferences(Context context) { 128 return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); 129 } 130 getNoThanksDelay(int noThanksCount)131 private static long getNoThanksDelay(int noThanksCount) { 132 return (noThanksCount > NO_THANKS_LONG_THRESHOLD) 133 ? NO_THANKS_LONG_DELAY : NO_THANKS_SHORT_DELAY; 134 } 135 getDismissDelay(int dismissCount)136 private static long getDismissDelay(int dismissCount) { 137 return (dismissCount > DISMISS_LONG_THRESHOLD) 138 ? DISMISS_LONG_DELAY : DISMISS_SHORT_DELAY; 139 } 140 finishActivity()141 private void finishActivity() { 142 Activity activity = getActivity(); 143 if (activity != null) { 144 activity.finish(); 145 } 146 } 147 } 148