| /* | 
 |  * Copyright (C) 2008 The Android Open Source Project | 
 |  * | 
 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 |  * you may not use this file except in compliance with the License. | 
 |  * You may obtain a copy of the License at | 
 |  * | 
 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, software | 
 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |  * See the License for the specific language governing permissions and | 
 |  * limitations under the License. | 
 |  */ | 
 |  | 
 | package android.renderscript; | 
 |  | 
 | import android.app.compat.CompatChanges; | 
 | import android.compat.annotation.ChangeId; | 
 | import android.compat.annotation.EnabledAfter; | 
 | import android.content.res.Resources; | 
 | import android.util.Slog; | 
 |  | 
 | import java.io.IOException; | 
 | import java.io.InputStream; | 
 |  | 
 | /** | 
 |  * The superclass for all user-defined scripts. This is only | 
 |  * intended to be used by the generated derived classes. | 
 |  * | 
 |  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a | 
 |  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration | 
 |  * guide</a> for the proposed alternatives. | 
 |  **/ | 
 | @Deprecated | 
 | public class ScriptC extends Script { | 
 |     private static final String TAG = "ScriptC"; | 
 |  | 
 |     /** | 
 |      * In targetSdkVersion 36 and above, Renderscript's ScriptC stops being supported | 
 |      * and an exception is thrown when the class is instantiated. | 
 |      * In targetSdkVersion 35 and below, Renderscript's ScriptC still works. | 
 |      */ | 
 |     @ChangeId | 
 |     @EnabledAfter(targetSdkVersion = 36) | 
 |     private static final long RENDERSCRIPT_SCRIPTC_DEPRECATION_CHANGE_ID = 297019750L; | 
 |  | 
 |     /** | 
 |      * Only intended for use by the generated derived classes. | 
 |      * | 
 |      * @param id | 
 |      * @param rs | 
 |      */ | 
 |     protected ScriptC(int id, RenderScript rs) { | 
 |         super(id, rs); | 
 |     } | 
 |     /** | 
 |      * Only intended for use by the generated derived classes. | 
 |      * | 
 |      * @param id | 
 |      * @param rs | 
 |      * | 
 |      */ | 
 |     protected ScriptC(long id, RenderScript rs) { | 
 |         super(id, rs); | 
 |     } | 
 |     /** | 
 |      * Only intended for use by the generated derived classes. | 
 |      * | 
 |      * | 
 |      * @param rs | 
 |      * @param resources | 
 |      * @param resourceID | 
 |      */ | 
 |     protected ScriptC(RenderScript rs, Resources resources, int resourceID) { | 
 |         super(0, rs); | 
 |         long id = internalCreate(rs, resources, resourceID); | 
 |         if (id == 0) { | 
 |             throw new RSRuntimeException("Loading of ScriptC script failed."); | 
 |         } | 
 |         setID(id); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Only intended for use by the generated derived classes. | 
 |      * | 
 |      * @param rs | 
 |      */ | 
 |     protected ScriptC(RenderScript rs, String resName, byte[] bitcode32, byte[] bitcode64) { | 
 |         super(0, rs); | 
 |         long id = 0; | 
 |         if (RenderScript.sPointerSize == 4) { | 
 |             id = internalStringCreate(rs, resName, bitcode32); | 
 |         } else { | 
 |             id = internalStringCreate(rs, resName, bitcode64); | 
 |         } | 
 |         if (id == 0) { | 
 |             throw new RSRuntimeException("Loading of ScriptC script failed."); | 
 |         } | 
 |         setID(id); | 
 |     } | 
 |  | 
 |     private static void throwExceptionIfScriptCUnsupported() { | 
 |         // Checks that this device actually does have an ABI that supports ScriptC. | 
 |         // | 
 |         // For an explanation as to why `System.loadLibrary` is used, see discussion at | 
 |         // https://android-review.googlesource.com/c/platform/frameworks/base/+/2957974/comment/2f908b80_a05292ee | 
 |         try { | 
 |             System.loadLibrary("RS"); | 
 |         } catch (UnsatisfiedLinkError e) { | 
 |             String s = "This device does not have an ABI that supports ScriptC."; | 
 |             throw new UnsupportedOperationException(s); | 
 |         } | 
 |  | 
 |         // Throw an exception if the target API is 36 or above | 
 |         String message = | 
 |                 "ScriptC scripts are not supported when targeting an API Level >= 36. Please refer " | 
 |                     + "to https://developer.android.com/guide/topics/renderscript/migration-guide " | 
 |                     + "for proposed alternatives."; | 
 |         Slog.w(TAG, message); | 
 |         if (CompatChanges.isChangeEnabled(RENDERSCRIPT_SCRIPTC_DEPRECATION_CHANGE_ID)) { | 
 |             throw new UnsupportedOperationException(message); | 
 |         } | 
 |     } | 
 |  | 
 |     private static synchronized long internalCreate(RenderScript rs, Resources resources, int resourceID) { | 
 |         throwExceptionIfScriptCUnsupported(); | 
 |         byte[] pgm; | 
 |         int pgmLength; | 
 |         InputStream is = resources.openRawResource(resourceID); | 
 |         try { | 
 |             try { | 
 |                 pgm = new byte[1024]; | 
 |                 pgmLength = 0; | 
 |                 while(true) { | 
 |                     int bytesLeft = pgm.length - pgmLength; | 
 |                     if (bytesLeft == 0) { | 
 |                         byte[] buf2 = new byte[pgm.length * 2]; | 
 |                         System.arraycopy(pgm, 0, buf2, 0, pgm.length); | 
 |                         pgm = buf2; | 
 |                         bytesLeft = pgm.length - pgmLength; | 
 |                     } | 
 |                     int bytesRead = is.read(pgm, pgmLength, bytesLeft); | 
 |                     if (bytesRead <= 0) { | 
 |                         break; | 
 |                     } | 
 |                     pgmLength += bytesRead; | 
 |                 } | 
 |             } finally { | 
 |                 is.close(); | 
 |             } | 
 |         } catch(IOException e) { | 
 |             throw new Resources.NotFoundException(); | 
 |         } | 
 |  | 
 |         String resName = resources.getResourceEntryName(resourceID); | 
 |  | 
 |         //        Log.v(TAG, "Create script for resource = " + resName); | 
 |         return rs.nScriptCCreate(resName, RenderScript.getCachePath(), pgm, pgmLength); | 
 |     } | 
 |  | 
 |     private static synchronized long internalStringCreate(RenderScript rs, String resName, byte[] bitcode) { | 
 |         //        Log.v(TAG, "Create script for resource = " + resName); | 
 |         throwExceptionIfScriptCUnsupported(); | 
 |         return rs.nScriptCCreate(resName, RenderScript.getCachePath(), bitcode, bitcode.length); | 
 |     } | 
 | } |