1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.development;
18 
19 import android.app.Notification;
20 import android.app.NotificationChannel;
21 import android.app.NotificationManager;
22 import android.app.PendingIntent;
23 import android.app.Service;
24 import android.content.Intent;
25 import android.os.IBinder;
26 import android.provider.Settings;
27 
28 import androidx.annotation.NonNull;
29 import androidx.annotation.Nullable;
30 
31 import com.android.settings.R;
32 
33 public class PageAgnosticNotificationService extends Service {
34 
35     private static final String NOTIFICATION_CHANNEL_ID =
36             "com.android.settings.development.PageAgnosticNotificationService";
37     private static final int NOTIFICATION_ID = 1;
38 
39     static final int DISABLE_UPDATES_SETTING = 1;
40 
41     private NotificationManager mNotificationManager;
42 
43     @Nullable
44     @Override
onBind(@onNull Intent intent)45     public IBinder onBind(@NonNull Intent intent) {
46         return null;
47     }
48 
49     // create a notification channel to post persistent notification
createNotificationChannel()50     private void createNotificationChannel() {
51         NotificationChannel channel =
52                 new NotificationChannel(
53                         NOTIFICATION_CHANNEL_ID,
54                         getString(R.string.page_agnostic_notification_channel_name),
55                         NotificationManager.IMPORTANCE_HIGH);
56         mNotificationManager = getSystemService(NotificationManager.class);
57         if (mNotificationManager != null) {
58             mNotificationManager.createNotificationChannel(channel);
59         }
60     }
61 
62     @Override
onCreate()63     public void onCreate() {
64         super.onCreate();
65         createNotificationChannel();
66     }
67 
buildNotification()68     private Notification buildNotification() {
69         // Get the title and text according to page size
70         boolean isIn16kbMode = Enable16kUtils.isUsing16kbPages();
71         String title =
72                 isIn16kbMode
73                         ? getString(R.string.page_agnostic_16k_pages_title)
74                         : getString(R.string.page_agnostic_4k_pages_title);
75         String text =
76                 isIn16kbMode
77                         ? getString(R.string.page_agnostic_16k_pages_text_short)
78                         : getString(R.string.page_agnostic_4k_pages_text_short);
79 
80         Intent notifyIntent = new Intent(this, PageAgnosticWarningActivity.class);
81         // Set the Activity to start in a new, empty task.
82         notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
83 
84         // Create the PendingIntent.
85         PendingIntent notifyPendingIntent =
86                 PendingIntent.getActivity(
87                         this,
88                         0,
89                         notifyIntent,
90                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
91 
92         Notification.Action action =
93                 new Notification.Action.Builder(
94                                 R.drawable.empty_icon,
95                                 getString(R.string.page_agnostic_notification_action),
96                                 notifyPendingIntent)
97                         .build();
98 
99         Notification.Builder builder =
100                 new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
101                         .setContentTitle(title)
102                         .setContentText(text)
103                         .setOngoing(true)
104                         .setSmallIcon(R.drawable.ic_settings_24dp)
105                         .setStyle(new Notification.BigTextStyle().bigText(text))
106                         .setContentIntent(notifyPendingIntent)
107                         .addAction(action);
108 
109         return builder.build();
110     }
111 
disableAutomaticUpdates()112     private void disableAutomaticUpdates() {
113         final int currentState =
114                 Settings.Global.getInt(
115                         getApplicationContext().getContentResolver(),
116                         Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
117                         0 /* default */);
118         // 0 means enabled, 1 means disabled
119         if (currentState == 0) {
120             // automatic updates are enabled, disable them
121             Settings.Global.putInt(
122                     getApplicationContext().getContentResolver(),
123                     Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
124                     DISABLE_UPDATES_SETTING);
125         }
126     }
127 
128     @Override
onStartCommand(@ullable Intent intent, int flags, int startId)129     public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
130         Notification notification = buildNotification();
131         if (mNotificationManager != null) {
132             mNotificationManager.notify(NOTIFICATION_ID, notification);
133         }
134 
135         // No updates should be allowed in page-agnostic mode
136         disableAutomaticUpdates();
137         return Service.START_NOT_STICKY;
138     }
139 }
140