19f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li/*
2f04335f899f2cce69f843692a3cb9cec229683c2tturney * Copyright (C) 2017 The Android Open Source Project
39f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li *
4f04335f899f2cce69f843692a3cb9cec229683c2tturney * Licensed under the Apache License, Version 2.0 (the "License");
5f04335f899f2cce69f843692a3cb9cec229683c2tturney * you may not use this file except in compliance with the License.
6f04335f899f2cce69f843692a3cb9cec229683c2tturney * You may obtain a copy of the License at
79f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li *
8f04335f899f2cce69f843692a3cb9cec229683c2tturney *      http://www.apache.org/licenses/LICENSE-2.0
99f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li *
109f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li * Unless required by applicable law or agreed to in writing, software
11f04335f899f2cce69f843692a3cb9cec229683c2tturney * distributed under the License is distributed on an "AS IS" BASIS,
12f04335f899f2cce69f843692a3cb9cec229683c2tturney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f04335f899f2cce69f843692a3cb9cec229683c2tturney * See the License for the specific language governing permissions and
14f04335f899f2cce69f843692a3cb9cec229683c2tturney * limitations under the License.
159f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li */
169f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
179f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Lipackage com.googlecode.android_scripting.facade;
189f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
199f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.app.Service;
209f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport android.content.Intent;
219f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
229f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.Log;
239f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.exception.Sl4aException;
249f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.jsonrpc.RpcReceiver;
259f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.jsonrpc.RpcReceiverManager;
269f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.rpc.RpcDeprecated;
279f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport com.googlecode.android_scripting.rpc.RpcMinSdk;
289f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
299f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.lang.reflect.InvocationTargetException;
309f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.lang.reflect.Method;
319f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Liimport java.util.Collection;
329f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
339f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Lipublic class FacadeManager extends RpcReceiverManager {
349f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
359f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  private final Service mService;
369f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  private final Intent mIntent;
379f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  private int mSdkLevel;
389f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
399f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  public FacadeManager(int sdkLevel, Service service, Intent intent,
409f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      Collection<Class<? extends RpcReceiver>> classList) {
419f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    super(classList);
429f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    mSdkLevel = sdkLevel;
439f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    mService = service;
449f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    mIntent = intent;
459f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  }
469f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
479f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  public int getSdkLevel() {
489f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    return mSdkLevel;
499f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  }
509f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
519f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  public Service getService() {
529f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    return mService;
539f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  }
549f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
559f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  public Intent getIntent() {
569f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    return mIntent;
579f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  }
589f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
599f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  @Override
609f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  public Object invoke(Class<? extends RpcReceiver> clazz, Method method, Object[] args)
619f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      throws Exception {
629f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    try {
639f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      if (method.isAnnotationPresent(RpcDeprecated.class)) {
649f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        String replacedBy = method.getAnnotation(RpcDeprecated.class).value();
659f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        String title = method.getName() + " is deprecated";
669f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        Log.notify(mService, title, title, String.format("Please use %s instead.", replacedBy));
679f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      } else if (method.isAnnotationPresent(RpcMinSdk.class)) {
689f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value();
699f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        if (mSdkLevel < requiredSdkLevel) {
709f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li          throw new Sl4aException(String.format("%s requires API level %d, current level is %d",
719f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li              method.getName(), requiredSdkLevel, mSdkLevel));
729f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        }
739f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      }
749f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      return super.invoke(clazz, method, args);
759f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    } catch (InvocationTargetException e) {
769f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      if (e.getCause() instanceof SecurityException) {
779f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        Log.notify(mService, "RPC invoke failed...", mService.getPackageName(), e.getCause()
789f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li            .getMessage());
799f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      }
809f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      throw e;
819f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    }
829f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  }
839f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li
849f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  public AndroidFacade.Resources getAndroidFacadeResources() {
859f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    return new AndroidFacade.Resources() {
869f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      @Override
879f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      public int getLogo48() {
889f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        // TODO(Alexey): As an alternative, ask application for resource ids.
899f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        String packageName = mService.getApplication().getPackageName();
909f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li        return mService.getResources().getIdentifier("script_logo_48", "drawable", packageName);
919f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li      }
929f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li    };
939f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li  }
949f32db87b486c93a0ea71eb1781ee45676b8bf8bXin Li}
95