Home | History | Annotate | Download | only in carrierdefaultapp
      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 com.android.carrierdefaultapp;
     18 
     19 import android.app.job.JobInfo;
     20 import android.app.job.JobParameters;
     21 import android.app.job.JobScheduler;
     22 import android.app.job.JobService;
     23 import android.content.ComponentName;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.net.ConnectivityManager;
     27 import android.net.Network;
     28 import android.net.NetworkCapabilities;
     29 import android.provider.Settings;
     30 import android.util.Log;
     31 
     32 import com.android.internal.telephony.TelephonyIntents;
     33 
     34 /**
     35  * Service to run {@link android.app.job.JobScheduler} job.
     36  * Service to monitor when there is a change to conent URI
     37  * {@link android.provider.Settings.Global#DEVICE_PROVISIONED DEVICE_PROVISIONED}
     38  */
     39 public class ProvisionObserver extends JobService {
     40 
     41     private static final String TAG = ProvisionObserver.class.getSimpleName();
     42     public static final int PROVISION_OBSERVER_REEVALUATION_JOB_ID = 1;
     43     // minimum & maximum update delay TBD
     44     private static final int CONTENT_UPDATE_DELAY_MS = 100;
     45     private static final int CONTENT_MAX_DELAY_MS = 200;
     46 
     47     @Override
     48     public boolean onStartJob(JobParameters jobParameters) {
     49         switch (jobParameters.getJobId()) {
     50             case PROVISION_OBSERVER_REEVALUATION_JOB_ID:
     51                 if (isProvisioned(this)) {
     52                     Log.d(TAG, "device provisioned, force network re-evaluation");
     53                     final ConnectivityManager connMgr = ConnectivityManager.from(this);
     54                     Network[] info = connMgr.getAllNetworks();
     55                     for (Network nw : info) {
     56                         final NetworkCapabilities nc = connMgr.getNetworkCapabilities(nw);
     57                         if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
     58                                 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
     59                             // force connectivity re-evaluation to assume skipped carrier actions.
     60                             // one of the following calls will match the last evaluation.
     61                             connMgr.reportNetworkConnectivity(nw, true);
     62                             connMgr.reportNetworkConnectivity(nw, false);
     63                             break;
     64                         }
     65                     }
     66                 }
     67             default:
     68                 break;
     69         }
     70         return false;
     71     }
     72 
     73     @Override
     74     public boolean onStopJob(JobParameters jobParameters) {
     75         return false;
     76     }
     77 
     78     // Returns true if the device is not provisioned yet (in setup wizard), false otherwise
     79     private static boolean isProvisioned(Context context) {
     80         return Settings.Global.getInt(context.getContentResolver(),
     81                 Settings.Global.DEVICE_PROVISIONED, 0) == 1;
     82     }
     83 
     84     /**
     85      * Static utility function to schedule a job to execute upon the change of content URI
     86      * {@link android.provider.Settings.Global#DEVICE_PROVISIONED DEVICE_PROVISIONED}.
     87      * @param context The context used to retrieve the {@link ComponentName} and system services
     88      * @return true carrier actions are deferred due to phone provisioning process, false otherwise
     89      */
     90     public static boolean isDeferredForProvision(Context context, Intent intent) {
     91         if (isProvisioned(context)) {
     92             return false;
     93         }
     94         int jobId;
     95         switch(intent.getAction()) {
     96             case TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED:
     97                 jobId = PROVISION_OBSERVER_REEVALUATION_JOB_ID;
     98                 break;
     99             default:
    100                 return false;
    101         }
    102         final JobScheduler jobScheduler =  (JobScheduler) context.getSystemService(
    103                 Context.JOB_SCHEDULER_SERVICE);
    104         final JobInfo job = new JobInfo.Builder(jobId,
    105                 new ComponentName(context, ProvisionObserver.class))
    106                 .addTriggerContentUri(new JobInfo.TriggerContentUri(
    107                         Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), 0))
    108                 .setTriggerContentUpdateDelay(CONTENT_UPDATE_DELAY_MS)
    109                 .setTriggerContentMaxDelay(CONTENT_MAX_DELAY_MS)
    110                 .build();
    111         jobScheduler.schedule(job);
    112         return true;
    113     }
    114 }
    115