15190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren/* 25190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* Copyright (C) 2014 The Android Open Source Project 35190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* 45190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* Licensed under the Apache License, Version 2.0 (the "License"); 55190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* you may not use this file except in compliance with the License. 65190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* You may obtain a copy of the License at 75190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* 85190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* http://www.apache.org/licenses/LICENSE-2.0 95190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* 105190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* Unless required by applicable law or agreed to in writing, software 115190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* distributed under the License is distributed on an "AS IS" BASIS, 125190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* See the License for the specific language governing permissions and 145190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren* limitations under the License. 155190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren*/ 165190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 175190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wrenpackage com.android.server.notification; 185190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 1985769915e7ef10bef2b5338ed8f04d9b787924fbJulia Reynoldsimport android.app.NotificationManager; 205190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wrenimport android.content.Context; 212445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynoldsimport android.net.Uri; 221d881a1e986c706963c254fbe2b6296a1cd10b75John Spurlockimport android.util.Log; 235190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wrenimport android.util.Slog; 245190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 25bbc469cecac9c50c342902d724bfa68acd140770Julia Reynoldsimport com.android.internal.annotations.VisibleForTesting; 26bbc469cecac9c50c342902d724bfa68acd140770Julia Reynolds 275190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren/** 280dbb7310088fdf2845861d2dc0e271812083e273Julia Reynolds * This {@link com.android.server.notification.NotificationSignalExtractor} notices noisy 295190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren * notifications and marks them to get a temporary ranking bump. 305190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren */ 315190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wrenpublic class NotificationIntrusivenessExtractor implements NotificationSignalExtractor { 321d881a1e986c706963c254fbe2b6296a1cd10b75John Spurlock private static final String TAG = "IntrusivenessExtractor"; 331d881a1e986c706963c254fbe2b6296a1cd10b75John Spurlock private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); 345190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 355190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren /** Length of time (in milliseconds) that an intrusive or noisy notification will stay at 365190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren the top of the ranking order, before it falls back to its natural position. */ 37bbc469cecac9c50c342902d724bfa68acd140770Julia Reynolds @VisibleForTesting 38bbc469cecac9c50c342902d724bfa68acd140770Julia Reynolds static final long HANG_TIME_MS = 10000; 395190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 405eab2b72afe5b20dc66c237b1cceedfc09de2d52Chris Wren public void initialize(Context ctx, NotificationUsageStats usageStats) { 415190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + "."); 425190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren } 435190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 44470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren public RankingReconsideration process(NotificationRecord record) { 455190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren if (record == null || record.getNotification() == null) { 465190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren if (DBG) Slog.d(TAG, "skipping empty notification"); 475190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren return null; 485190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren } 495190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 50bbc469cecac9c50c342902d724bfa68acd140770Julia Reynolds if (record.getFreshnessMs(System.currentTimeMillis()) < HANG_TIME_MS 51bbc469cecac9c50c342902d724bfa68acd140770Julia Reynolds && record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) { 522445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds if (record.getSound() != null && record.getSound() != Uri.EMPTY) { 532445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds record.setRecentlyIntrusive(true); 542445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds } 552445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds if (record.getVibration() != null) { 562445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds record.setRecentlyIntrusive(true); 572445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds } 582445037bb9a98fd00bfa14c5b99b09026e8ffed7Julia Reynolds if (record.getNotification().fullScreenIntent != null) { 590dbb7310088fdf2845861d2dc0e271812083e273Julia Reynolds record.setRecentlyIntrusive(true); 600dbb7310088fdf2845861d2dc0e271812083e273Julia Reynolds } 615190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren } 625190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren 63eb3dca71b5df7fdf6299a3e65eb5d6fe8cb7bcbcJulia Reynolds if (!record.isRecentlyIntrusive()) { 64eb3dca71b5df7fdf6299a3e65eb5d6fe8cb7bcbcJulia Reynolds return null; 65eb3dca71b5df7fdf6299a3e65eb5d6fe8cb7bcbcJulia Reynolds } 66eb3dca71b5df7fdf6299a3e65eb5d6fe8cb7bcbcJulia Reynolds 67470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren return new RankingReconsideration(record.getKey(), HANG_TIME_MS) { 685190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren @Override 695190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren public void work() { 70470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren // pass 71470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren } 72470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren 73470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren @Override 74470c1accf5a54f9844a779eafab74e63c09342b5Chris Wren public void applyChangesLocked(NotificationRecord record) { 75309d1c83e9fab971dab68cb6395c3f515ba9b85bJulia Reynolds // there will be another reconsideration in the message queue HANG_TIME_MS 76309d1c83e9fab971dab68cb6395c3f515ba9b85bJulia Reynolds // from each time this record alerts, which can finally clear this flag. 77309d1c83e9fab971dab68cb6395c3f515ba9b85bJulia Reynolds if ((System.currentTimeMillis() - record.getLastIntrusive()) >= HANG_TIME_MS) { 78309d1c83e9fab971dab68cb6395c3f515ba9b85bJulia Reynolds record.setRecentlyIntrusive(false); 79309d1c83e9fab971dab68cb6395c3f515ba9b85bJulia Reynolds } 805190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren } 815190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren }; 825190c0fefac9923931b5c1c02cab2d00c2d6b82bChris Wren } 8354bbef435ed857fc68941672799fc8001c101119Chris Wren 8454bbef435ed857fc68941672799fc8001c101119Chris Wren @Override 8554bbef435ed857fc68941672799fc8001c101119Chris Wren public void setConfig(RankingConfig config) { 8654bbef435ed857fc68941672799fc8001c101119Chris Wren // ignore: config has no relevant information yet. 8754bbef435ed857fc68941672799fc8001c101119Chris Wren } 88c861a3ddbc9b6cb193e71dbb5da6162d119e2e98Julia Reynolds 89c861a3ddbc9b6cb193e71dbb5da6162d119e2e98Julia Reynolds @Override 90c861a3ddbc9b6cb193e71dbb5da6162d119e2e98Julia Reynolds public void setZenHelper(ZenModeHelper helper) { 91c861a3ddbc9b6cb193e71dbb5da6162d119e2e98Julia Reynolds 92c861a3ddbc9b6cb193e71dbb5da6162d119e2e98Julia Reynolds } 9354bbef435ed857fc68941672799fc8001c101119Chris Wren} 94