1 /* 2 * Copyright (C) 2017 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 android.app.usage; 18 19 import android.annotation.SystemApi; 20 import android.app.Service; 21 import android.app.usage.ICacheQuotaService; 22 import android.content.Intent; 23 import android.os.Bundle; 24 import android.os.Handler; 25 import android.os.IBinder; 26 import android.os.Looper; 27 import android.os.Message; 28 import android.os.RemoteCallback; 29 import android.util.Log; 30 import android.util.Pair; 31 32 import java.util.List; 33 34 /** 35 * CacheQuoteService defines a service which accepts cache quota requests and processes them, 36 * thereby filling out how much quota each request deserves. 37 * {@hide} 38 */ 39 @SystemApi 40 public abstract class CacheQuotaService extends Service { 41 private static final String TAG = "CacheQuotaService"; 42 43 /** 44 * The {@link Intent} action that must be declared as handled by a service 45 * in its manifest for the system to recognize it as a quota providing service. 46 */ 47 public static final String SERVICE_INTERFACE = "android.app.usage.CacheQuotaService"; 48 49 /** {@hide} **/ 50 public static final String REQUEST_LIST_KEY = "requests"; 51 52 private CacheQuotaServiceWrapper mWrapper; 53 private Handler mHandler; 54 55 @Override onCreate()56 public void onCreate() { 57 super.onCreate(); 58 mWrapper = new CacheQuotaServiceWrapper(); 59 mHandler = new ServiceHandler(getMainLooper()); 60 } 61 62 @Override onBind(Intent intent)63 public IBinder onBind(Intent intent) { 64 return mWrapper; 65 } 66 67 /** 68 * Processes the cache quota list upon receiving a list of requests. 69 * @param requests A list of cache quotas to fulfill. 70 * @return A completed list of cache quota requests. 71 */ onComputeCacheQuotaHints( List<CacheQuotaHint> requests)72 public abstract List<CacheQuotaHint> onComputeCacheQuotaHints( 73 List<CacheQuotaHint> requests); 74 75 private final class CacheQuotaServiceWrapper extends ICacheQuotaService.Stub { 76 @Override computeCacheQuotaHints( RemoteCallback callback, List<CacheQuotaHint> requests)77 public void computeCacheQuotaHints( 78 RemoteCallback callback, List<CacheQuotaHint> requests) { 79 final Pair<RemoteCallback, List<CacheQuotaHint>> pair = 80 Pair.create(callback, requests); 81 Message msg = mHandler.obtainMessage(ServiceHandler.MSG_SEND_LIST, pair); 82 mHandler.sendMessage(msg); 83 } 84 } 85 86 private final class ServiceHandler extends Handler { 87 public static final int MSG_SEND_LIST = 1; 88 ServiceHandler(Looper looper)89 public ServiceHandler(Looper looper) { 90 super(looper, null, true); 91 } 92 93 @Override handleMessage(Message msg)94 public void handleMessage(Message msg) { 95 final int action = msg.what; 96 switch (action) { 97 case MSG_SEND_LIST: 98 final Pair<RemoteCallback, List<CacheQuotaHint>> pair = 99 (Pair<RemoteCallback, List<CacheQuotaHint>>) msg.obj; 100 List<CacheQuotaHint> processed = onComputeCacheQuotaHints(pair.second); 101 final Bundle data = new Bundle(); 102 data.putParcelableList(REQUEST_LIST_KEY, processed); 103 104 final RemoteCallback callback = pair.first; 105 callback.sendResult(data); 106 break; 107 default: 108 Log.w(TAG, "Handling unknown message: " + action); 109 } 110 } 111 } 112 } 113